2014-11-07 4 views
2

У меня было интервью для позиции разработчика программного обеспечения. Это было телефонное интервью. Был задан вопрос, и это меня прослушивало весь деньСамый быстрый алгоритм поиска слова в сетке поиска слов

Интервьюер попросил меня придумать общий подход для поиска слова в сетке поиска слов. Для простоты нет необходимости беспокоиться о ограничениях памяти или искать по диагонали по сетке (слева направо и сверху вниз).

Лучшее, что я мог придумать было создать хэш-карту при запуске программы сетки (перед вызовом слово искать каждый раз) ... есть это создать хэш-карту характера =>строк, col индексы. Таким образом, вы можете выполнить начальное сканирование в O (1) раз. А затем оттуда в основном сканируют слева направо или сверху вниз.

У меня сложилось впечатление, что было лучшее решение, и я еще не был там. Каков самый быстрый алгоритм для решения такой проблемы?

+0

Подсчитаем ли мы время предварительной расстановки, когда говорим «быстрее»? Если нет, то мы можем просто прекомпретировать все, и все запросы будут O (1). – irrelephant

+0

Если у вас есть вопрос «пожалуйста, прочитайте, что хотел интервьюер». Боюсь, это невозможно. Если вы хотите знать, что они имели в виду, то, возможно, последуйте за тем, кто задает вопрос. Для этого существует огромный спектр решений, и для выбора «лучшего» требуется более подробная информация, чем приведенная здесь. – HostileFork

ответ

0

Если память не является проблемой, и я могу препроцессировать данные, то я бы:

  1. Сделать строковое представление сетки в строке-мажорных порядке. Это для поиска по горизонтали.
  2. Сделайте строковое представление сетки в порядке столбцов, для поиска по вертикали.

Когда дано слово для поиска, я хотел бы использовать стандартный алгоритм поиска (KMP, Boyer-Moore и т.д.):

  1. Искать слово в строке-мажорные строки.
  2. Обратное слово и поиск в строке строки.
  3. Поиск слова в строке столбца.
  4. Обратное слово и поиск в строке столбца.

Это дает хороший баланс между простотой, использованием памяти и скоростью. Фактически, это мертво просто, потому что вам не нужно будет реализовывать алгоритм поиска. Просто используйте то, что предоставляется библиотекой времени выполнения.

Конечно, вы можете легко изменить стандартный алгоритм поиска, чтобы рассматривать двумерную сетку как одномерную строку без фактического выполнения преобразования загодя. Это сложнее и будет немного медленнее в поиске, чем предварительная обработка, но для этого потребуется меньше памяти.

Выполнение его на месте с помощью одного сканирования осложняется. Но вы можете выполнять горизонтальные поиски (т. Е. Слева направо и справа налево) достаточно легко в одном сканировании. И вертикальные поиски в одном сканировании. Вы просто искали бы две разные строки за один проход: слово и обратную версию слова.

+0

Это ** ужасный ** метод. Время найти каждое слово O (4n), где n - количество символов в головоломке. Если вы добавите диагонали, ваш алгоритм взлетает на O (8n). Обе эти оценки игнорируют тот факт, что ваш алгоритм найдет слова не в головоломке. Для тех, кто ищет быстрое решение, просто знайте, что эта проблема может быть решена в O (n * m) времени, где n - это число раз появляется первый символ, а m - количество раз, когда последний символ появляется для всех слов, имеющих 2 или более символов. Все однобуквенные слова можно найти в O (1) раз. – deAtog

+0

@deAtog: Я заявил, что это не самый быстрый способ сделать это, но он линейный. Ваш O (n * m) может быть намного хуже, чем O (4n). В зависимости от размера сетки и количества поисковых запросов, которые вы собираетесь делать, реализация модифицированного метода Aho-Corasick trie и поиска, вероятно, превзойдет любой из наших заявленных методов. Кроме того, вам придется объяснить, как мой метод может привести к поиску слов, которых нет. –

+0

Поскольку вы присоединяетесь к столбцам/строкам, ваш метод найдет слова, которые переносятся из одного столбца/строки в следующий. Для обеспечения того, чтобы найденное слово не пересекало границу строки/столбца, потребуется дополнительная работа. Мой метод никогда не будет хуже вашего метода, потому что нужно оценить только часть комбинаций n * m, подавляющее большинство может быть пропущено. Из тех, которые должны учитывать только одно направление, и слово либо соответствует, либо нет. – deAtog

-1

Я бы сказал, что он хотел, чтобы вы настаивали на разъяснении. Если вы ищете слов, то я согласен с вашим подходом. Если вы ищете одно слово, линейный поиск первой буквы с последующим поиском в каждом направлении для остальной части слова будет быстрее.

+0

Это не намного лучше, чем метод Джима. Преимущества этого подхода заключаются в том, что вы не дублируете головоломку таким образом, чтобы вы могли находить слова не в головоломке, а первый символ слова находится в O (n) времени, а не O (4n) время или O (8n), если вы включаете диагонали. Если бы я был интервьюером, я бы рассмотрел оба этих ответа как нечто среднее разработчик придумать, с вашим решением, только немного лучше, чем Джим. – deAtog

Смежные вопросы