Код
#статьи

Задача: ищем самый длинный общий префикс у элементов массива строк

Решаем задачи, которые дают программистам на собеседованиях в IT-компаниях. Сегодня ищем общий префикс в массиве строк.

Иллюстрация: Polina Vari для Skillbox Media

Сергей Голицын


Senior Java Developer в Covalent Inc. и преподаватель. Больше семи лет в Java-разработке. В свободное время судит хакатоны и делится опытом с начинающими программистами. Пишет статьи для «Хабра» и Medium. Ведёт телеграм-каналы «Полезные ссылки около Java» и Cracking code interview.


Условие. Необходимо написать функцию, которая находит самый длинный общий префикс среди элементов массива строк. Если такого префикса нет, программа должна вернуть пустую строку.

Ввод и вывод. Пример 1

Ввод: strs = ["flower", "flow", "flight"]
Вывод: "fl"

Ввод и вывод. Пример 2

Ввод: strs = ["dog", "racecar", "car"]
Вывод: ""
// Пояснение: у этих строк нет общего префикса.

Решить эту задачу самостоятельно и на разных языках программирования можно на LeetCode. Наше решение взято из Telegram-канала Сергея Cracking code interview.

Решение

Чтобы решить эту задачу, мы будем использовать принцип «скользящего окна». Его суть в том, что мы берём две строки и начинаем посимвольно сравнивать их, как бы смотря на них через окно.

Для нашей задачи это самый простой и очевидный метод решения. Мы возьмём два указателя — начала и конца — и будем перемещать их в зависимости от условий: нашли или не нашли одинаковую последовательность символов.

На старте алгоритма первая строка массива будет считаться общим префиксом. В процессе мы будем сравнивать её с другими строками и отрезать с конца символы, которые не совпадают. И так с каждой строкой массива.

Полный алгоритм такой:

  • Сначала проверяем размер массива: если массив пустой, то и общий префикс — пустая строка. А если в массиве только один элемент, то он и будет общим префиксом.
  • В остальных случаях берём первую строку массива и принимаем её за самый длинный общий префикс.
  • Ставим два указателя: один будет следить за индексом последнего символа, который совпал с нашим общим префиксом, а второй будет перемещаться по строкам посимвольно.
  • Перебираем элементы массива, начиная со второго — сравниваем символы в этом элементе с символами общего префикса. Если символы равны, увеличиваем индекс общего префикса на один, если нет — просто идём дальше.
  • После проверки очередной строки массива отрезаем от общего префикса лишние символы — по индексу, который сохранён в нашем указателе.

Вот как этот алгоритм будет реализован на Java:

public String longestCommonPrefix(String[] strs) {
    if(strs.length == 0){
      return "";
    }
    if (strs.length == 1){
      return strs[0];
    }
     
    String rez = strs[0];
    for(int i = 1; i < strs.length; i ++){
      String cur = strs[i];
      int reader = 0;
      int lastCommon = 0;
      while(reader < rez.length() && reader < cur.length()){
        if(rez.charAt(reader) == cur.charAt(reader)){
          lastCommon ++;
        } else {
          break;
        }
        reader++;
      }
      rez = rez.substring(0, lastCommon);
    }
    return rez;
  }

Результаты

Временная сложность: O(n) — так как мы перебирали все элементы массива.

Ёмкостная сложность: O(1) — нам нужно заранее определённое количество места в памяти (максимальный размер памяти — длина первого слова в массиве).

Проверьте свой английский. Бесплатно ➞
Нескучные задания: small talk, поиск выдуманных слов — и не только. Подробный фидбэк от преподавателя + персональный план по повышению уровня.
Пройти тест
Понравилась статья?
Да

Пользуясь нашим сайтом, вы соглашаетесь с тем, что мы используем cookies 🍪

Ссылка скопирована