Про розв'язок напишу тепер. Я вам відразу скажу, шо курс по алгоритмам і структурам даних, який я проходив пів року тому - не минув дарма, бо я відразу зрозумів, шо нам треба два курсора, один завжди був би поперед іншого.
Ідея в тім, шо у нас є геш таблиця, котрі тримає інфу про індекси символів. Також у нас є два оці курсори. Перший на 0 індексі, другий на 1.
І далі ми перевіряємо - якшо символ під правим курсором вже є в таблиці, і його індекс більший за лівий курсор - це означає, шо ми натрапили на дублікат символу, і все, шо є між попереднім значенням правого курсора і лівим курсором - унікальний рядок, в котрому символи не повторюються.
Коли ми натрапляємо на такий дубль, то нам тре зберегти довжину того унікального підрядка. Ну а потім ми збільшуємо правий курсор на 1, а лівий встановлюємо в (попередній індекс символу, котрий зустріли + 1) і перевіряємо то все заново. І ще треба не забувати заносити в геш таблицю індекси тих символів, котрі зустрічаємо.
Нехай у нас є такий рядок
Спершу лівий курсор на 1, а правий на 2.
Ми дивимося в таблицю, і бачимо, шо 2 в нас ще там нема, тому рухаємось вперід, заносячи індекс двійки в таблицю.
Далі у нас лівий курсор так само на 1, а правий вже на 3. Ми не бачимо 3 в таблиці, тому рухаємось далі, і заносимо інфу про цей символ в таблицю.
Тепер у нас лівий курсор на 1, а правий на 1. Ми дивимось в таблицю, і бачимо, шо ми вже зустрічали 1 під індексом 0, і наш лівий курсор як раз на нього вказує. Це означає, шо нам тепер тре відняти індекс правого курсора (3) від індексу лівого курсора (0), і нас виходе 3 - це довжина підрядка, в якому символи не повторюються.
Тепер ми рухаємо лівий курсор на (останній індекс дубльованого символу + 1, тобто 0 + 1 = 1)=, а правий курсор просто інкрементуємо.
Тепер лівий курсор на 2, а правий на 4. 4 ще не було в таблиці, тому заносимо його, і рухаємось далі.
Тепер лівий курсор так само на 2, а правий на 5. 5 так само новеньке для нас.
Тепер правий курсор дійшов кінця рядка, і ми беремо його індекс (5) і віднімаємо від нього індекс лівого курсора (1) і виходе 4. Але це не дуже правильно, бо насправді довжина підрядка - 5, а не 4. І оце проблєма індексів, яку я постійно маю. Воно працює добре для того, що йде всередині рядка, але коли ми доходимо до кінця, то одинички не вистачає, тому цей випадок я окремо обробляю, в кінці.
function lengthOfLongestSubstring(s: string): number {
let left = 0,
right = 1;
const table = new Map<string, number>();
table.set(s[left], left);
let max = 0;
while (right < s.length) {
const check = s[right];
if (table.has(s[right]) && table.get(s[right]) >= left) {
max = Math.max(max, right - left);
left = table.get(s[right]) + 1;
}
table.set(s[right], right);
right++;
}
max = Math.max(max, s.length - left);
return max;
}