Найти наиболее длинный отрезок из двух значений в массиве
Дана строка чисел 6 2 5 2 8 2 2 8 2 6 8 ( длина 11 )
наиболее длинный отрезок из двух значений для данной строки будет 2 8 2 2 8 2 ( длиной 6 )
Как сделать это в коде, не понимаю, подскажите, если есть идеи какие то.
(желательно golang)
Ответы (3 шт):
Вашу задачу можно решить за O(n). Просто храните максимальный размер отрезка из нужных двух чисел, и "счётчик". Обе этих переменных изначально должны быть равны 0. Идите по массиву, и если текущий рассматриваемый элемент равен одному из тех двух чисел, прибавляйте к счётчику 1. Если вы встретили элемент, не равный тем двум числам, то текущий отрезок из подходящих чисел закончился. Тогда обновите максимальный размер отрезка, и присвойте счётчику значение 0. И так до конца. Потом после цикла нужно будет снова обновить максимальный размер отрезка. Потом выводите его.
1)создать переменную содержащую длину самого длинног отрезка на данный момент - `max = -1`\
2)создаьб переменную счетчик для текущей строки `currentLen = 0`\
3)создать переменную, отвечающую за хранение начала самой длинной последовательности `maxPosition` \
`k = 0`\
4)Считываем входную строку чисел `str`\
5)ставим указатель `i` по строке на начальное положение
6)считываем `str[i]` и `str[i+1]` если str[i+1] == str[i], то i+2 и т.д. , отдельный счетчик сделай\
7)`k++`\
8)если не дошли до конца строки `str` читаем `str[i+k]`\
9)если `str[i+k]` равен `str[i]` или `str[i+1]` то `currentLen++` и к п.7, иначе п.10\
10)если `currentLen < max` то `max = currentLen`, `maxPosition = i`\
11) если `i < длины строки-1` то `i++` и к п.6, иначе к п.12\
12)конец
Этот алгоритм должен решать вашу задачу, разберитесь и реализуйте его
Делаете два индекса - left и right, и словарь-счётчик counter, хранящий символы и для каждого счётчик количества в текущем окне, и счётчик distinct - количество различных символов в текущем окне.
Поставили left на нулевой индекс. Начали двигать right, на каждом шаге увеличиваем счётчик для очередного символа counter[a[right]] += 1.
Если новое значение этого счётчика стало равно 1 - увеличиваем distinct.
Если distinct стал равным 3, останавливаемся, и фиксируем разницу right-left, обновляем максимум длины интервала.
Теперь двигаем left, на каждом шаге уменьшая счётчик для очередного символа counter[a[left]] -= 1.
Если новое значение этого счётчика стало равно 0 - уменьшаем distinct.
Если distinct стал равным 2, останавливаемся, снова начинаем двигать right
Алгоритм линейный