В этой задаче LeetCode нас просят найти длину самой длинной строки символов в предоставленной строке, которая не содержит повторяющихся символов. Другими словами, в строке hello
самой длинной подстрокой без повторяющихся символов является hel
(с длиной 3).
Основным методом решения этой проблемы является «движущееся окно», и все нижеприведенные подходы используют его в той или иной форме.
Решение №1: Двойной цикл с набором
Это был мой первый и наименее сложный метод. В нем мы перебираем один раз все символы в предоставленной строке, а затем для каждого из них мы перебираем оставшиеся символы, добавляя каждый в набор, пока не найдем повторяющийся символ. В этот момент мы проверяем, является ли это самой длинной найденной строкой, и сохраняем ее длину, если это так. Это повторяется до конца строки, пока мы не найдем нашу самую длинную подстроку.
Решение № 2: Массив
Это решение похоже на предыдущее, но вместо этого использует массив для хранения текущей строки, которая имеет то преимущество, что она упорядочена и имеет функции splice
и indexOf
, которые делают это решение особенно удобным для глаз и устраняют необходимость во вложенных петля.
Решение № 3: Карта
Пользователь LeetCode niath разместил это замечательное решение, используя карту, которую я скорректировал, чтобы улучшить читаемость. Он использует концепцию движущегося окна, но использует Карты для молниеносного поиска. Интересно, что поскольку Map представляет собой пару ключ-значение, мы можем использовать букву в качестве ключа, а позицию, которую она занимает в строке, в качестве значения:
Решение № 4: Установите
Это решение было вдохновлено решением jeantimex для Java и основано на концепции карты, но немного упрощает работу, чтобы вместо этого использовать набор. Это дает преимущество в уменьшении сложности кода, но, возможно, ухудшает читабельность:
Сравнение решений
Все подходы (за исключением двойного цикла) имеют одинаковую производительность и различаются между тестами настолько, что ими можно пренебречь:
Однако интересно то, что процессор LeetCode настолько оптимизирован для работы с массивами, что если вы начнете все эти подходы с первого преобразования строки в массив (используя string.split('')
), вы увидите прирост производительности по всем направлениям.