Создал Telegram канал, в котором рассказываю о работе в Google, подготовке к собеседованиям и жизни в Лондоне. Подписывайтесь: t.me/saschalukin
@manOfPlanetEarth6 ай бұрын
Саша, сделай уже, плз, плейлисты на канале☝🏼☝🏼 С задачами, пр. и тд. Скомпонуй видосы.
@albertbrawls6 ай бұрын
Оаоаао что это?! Метод двух указателей!
@boriskogan-lerner74856 ай бұрын
Если правильно понимаю, в некоторых случаях операции с хешем могут стремиться к O(logN)=> общее время будет приближаться к O(N*logN). Где N- длинна строки т.к. операции выполняются дважды, а размер сета в худшем случае будет N/2 (Среднее членов арифметической прогрессии(An+A1)/2). 1/2*2=1 П.с. Часа полтора потратил что бы понять что что-бы решит проблему коллизий при хешировании нам надо выделять примерно "очень много" памяти на каждый сет, установить жесткое ограничение в размере строки и используемом наборе символов а так же тратиться на сжать/разжать данные в этой строке
@sobirabdulxair90016 ай бұрын
один из редких каналов, где разбирают и объясняют по-человечески без лишнего пафоса. жду с нетерпением каждого разбора.
@АндрейЖданов-г8ф6 ай бұрын
О иннополис на фоне на превьюшке
@cablook_egja6 ай бұрын
простой перебор можно сократить и до n^2, если просто обновлять сет после первого цикла а is_acceptable = True оставить на своём месте. ну и третий цикл можно будет убрать. На лит коде даже заработало. Для скользящего окна вот ещё альтернатива, с помощью словаря на python: def longest_substr(s): answer = 0 left = 0 hash_set = {} for right in range(len(s)): char = s[right] if char in hash_set and hash_set[char] >= left: left = hash_set[char] + 1 else: answer = max(answer, right - left + 1) hash_set[char] = right return answer Спасибо за видео
@TTTuTTT3 ай бұрын
И даже еще проще брутфорс можно сделать - вообще без этого is_acceptable, просто если в сете есть новая буква, то выходим из второго цикла, а потом проверяем больше ли сайз нашего сета, чем наш ответ и все.
@MrKryuk6 ай бұрын
Саша, спасибо за разборы. Косательно этого решения догадался про указатель `right`, что нет смысла увеличивать его, но не догадался про перемещение left.
@mndevitmndevit6 ай бұрын
Как же я долго ждал нового видео, спасибо тебе огромное! Вот бы они выходили чаще)
@Eldertri6 ай бұрын
Саша, привет! Спасибо за интересное видео. Единственное, ты слегка меня запутал когда сказал, что "удаляем, пока в сете есть повторяющиеся символы" - по факту, в сете они не повторяются. Наверное, лучше было бы сказать что удаляем, пока не удалим ПОВТОРИВШИЙСЯ символ)
@kalts_daniil6 ай бұрын
Я только что решал задачу: Longest Substring Without Repeating Characters, и вуаля, тут видео на sliding window подъехало 🔥 Спасибо!
@ghostlynomad77886 ай бұрын
Кстати на днях сидел решал эту задачу на leetcode , и она у меня не прошла последний тест из-за Time Limit Exceeded (986 / 987 testcases passed). Мой подход был такой - я собирал все уникальные подстроки (в отдельном методе я проверял что подстрока состоит из уникальных символов) в лист и затем с помощью компаратора сортировал по длине и возвращал длину последнего элемента
@Денис-ж3ф5р6 ай бұрын
Да просто алгосы везде одинаковые +-
@Дмитрий-л3я7ы6 ай бұрын
@@ghostlynomad7788 не мудрено, что по времени не прошел. Мало того, что собирал лист со сложностью n в квадрате, а то и n в кубе, так потом еще и добавил n*log(n) (я про сортировку). Ничего медленнее мне кажется тут уже не придумать))
@ghostlynomad77886 ай бұрын
@@Дмитрий-л3я7ы больше ни до чего не додумался ) и да, сложность сборки листа n в кубе🙈
@ghostlynomad77886 ай бұрын
@@Дмитрий-л3я7ы n в кубе на самом деле) но больше ни до чего не додумался за пару дней
@badishow48076 ай бұрын
На пробнике ЕГЭ подобная задача попадалась (24-е задание). Решил очень похожим способом Видео, как всегда, интересное. Благодарю за контент!
@ЛевАронов6 ай бұрын
тоже сдаю егэ, как раз захотел выучить алгоритм чтобы если что использовать) да и в целом полезная вещь
@romanpritkov11076 ай бұрын
но там тебе на сложность наплевать в егэ
@ладно-з5б6 ай бұрын
@@romanpritkov1107 не, n^3 такие задачи не делает, либо сотню условий надо проставлять, чтобы там скипало
@ivankondratyev23636 ай бұрын
реализация "простого" решения убила... я даже и не подумал что так можно XD
@heybeachMIN6 ай бұрын
Спасибо ОГРОМНОЕ за такой подробное объяснение, всё понятно теперь) Было бы круто увидеть подобное объяснение но про деревья))
@kirillschcerbinin70686 ай бұрын
spasibo, Sasha za detalniy razbor. Видосы становятся все лучше и лучше по качеству, харош
@suuron6 ай бұрын
Когда это два указателя стали чем-то удивительным(учусь в школе, смотрел пару записей собесов, почти в каждом были два указателя, так что думал, что это база)
@borys78376 ай бұрын
Избыточность в расчете answer. Его стоит пересчитывать в случае повторения буквы и последний раз когда заканчиваем всю функцию.
@crimfi6 ай бұрын
На асимптотику это не влияет, + можно написать контртест для которого пересчёт все равно будет происходить на каждом шаге
@AlexanderRadchenko6 ай бұрын
Да и ещё можно оптимизировать удаление из множества. Там не нужен поиск в множестве, достаточно простого сравнения символов.
@TurboGamasek2286 ай бұрын
@@crimfi на асимптотику не влияет, а на константу влияет
@crimfi6 ай бұрын
@@TurboGamasek228 можно написать тест, для которого константа не изменится, при оценке рассматриваем худший случай
@leomysky4 ай бұрын
Спасибо, что сделал это ценой 2 свичей
@АндрейАртамонов-ъ6щ6 ай бұрын
Первый раз за 10 лет в айти нашел нормально объясняющего на русском человека. Мне это конечно не пригодится, но было интересно 👍
@panfilovandrey6 ай бұрын
Очень хорошо объясняешь, респект. Алгоритм полного перебора можно немного оптимизировать, если не перебирать тупо все подстроки, а начинать с самой большой и двигаться к уменьшению, или, если уже нашли подстроку длиной 3, рассматривать только большие, это чуть-чуть сократит затраты, но, конечно, не будет лучше, чем скользящий алгоритм.
@rickgmv6 ай бұрын
Спасибо за классное объяснение, а то я когда на литкоде пыхтел над этими задачами с окном, чуть мозг не сломал, разбирая этот алгоритм
@flake16046 ай бұрын
За Иннополис за заднем фоне превью лайк)
@alexandreabramtsev91606 ай бұрын
Я конечно дико извиняюсь, но это круто и изящно! Придумал на лету тоже вариант O(n), но он немного сложнее и кушает больше памяти - на каждый индекс массива создавать отдельный сет и добавлять в него пока "дубль" символа не встретится. Метод скользящего окна намного красивее!
@user5555-s9e6 ай бұрын
Привет, хотел выразить тебе огромное спасибо. Посмле просмотра видео про гугл и инжерена. Мне вернулся дух программиста. Начал вести фриланс и параллельно изучаю собесы
@kuroiumi99496 ай бұрын
Ура ура! С возвращением, Сань :) Круто что ты стал записывать видео чаще))
@levhab5 ай бұрын
Ооо, мы этот алгоритм в школе называли "Метод двух индексов". Он очень помогал в 24 задании ЕГЭ по Информатике
@kiminomeha6 ай бұрын
О да, это очень классный алгоритм. Его еще называют методом двух указателей. Все, кто к ЕГЭ по информатике готовится, учат его, довольно эффективный и гибкий алгоритм
@Whispered__Wisdom6 ай бұрын
Привет, пожалуста продолжай, очень полезно и информативно, сейчас активно пытаюсь прокачать алгоритмы и твои видосы прям то-что нужно!!!
@vladimira93606 ай бұрын
Приятно осознавать, что я бы решил подобным образом.
@VDlasov6 ай бұрын
Было интересно изучить. Главное с апреля начать
@artemkashipov98656 ай бұрын
по моему алгоритм можно улучшить используя bitset для хранения мапы элементов и то сколько раз они встретились
@stas-web6 ай бұрын
Спасибо, отличная подача. Без воды и смс. Успехов.
@_AbUser6 ай бұрын
Клевый способ. А можно подгонкой размеров окна подобным способом находить всякие локальные максимумы, точки перегиба и прочее на каком ть временном ряде? По скольку они там формируются в вообще произвольной периодичностью.. ))) Было бы как раз...
@appngo63746 ай бұрын
Я на практике редко пользуюсь конструкцией while. В 1 проценте случаев) Можно еще решить вот так. Решение без скользящего окна. Хотя суть очень похожа. fun getMaxUniqueWithSet(input: String): Int { var maxSequence = 0 val set = mutableSetOf() input.forEach { c -> if (set.contains(c)) { if (set.size > maxSequence) { maxSequence = set.size } set.clear() } set.add(c) } return max(maxSequence, set.size) }
@Дмитрий-л3я7ы6 ай бұрын
Спасибо за видео! Сам около года назад сидел плотно в литкоде, задачи на скользящее окно были одними из любимых) Увидел условие, решил проверить сам себя, решу ли ее сейчас. Минут за 5 решил, не с первого раза, сначала подзабыл немного последовательность действий, пошел по неправильному пути. Оставлю тут свое решение (на js правда), оно немного отличается от решения в видео (вместо двух while у меня for и внутри него while, ну и без if/else, более линейно) function maxLen(str) { let maxLen = 0 let left = 0 const uniques = new Set() for (let right = 0; right < str.length; right++) { const current = str[right] while(uniques.has(current)) { uniques.delete(str[left]) left++ } uniques.add(current) maxLen = Math.max(maxLen, right - left + 1) } return maxLen } console.log(maxLen('axbxcxd')) // 3
@rof3leo6 ай бұрын
какая асимптотика?
@Дмитрий-л3я7ы6 ай бұрын
@@rof3leo O(n) по времени и памяти
@ArtsiomShendzikau6 ай бұрын
Спасибо за видео! Какие еще задачи можно решать методом скользящего окна?
@ВладимирКалинин-и8т6 ай бұрын
Это решение более эффективно, чем предложенное автором. class Solution: def lengthOfLongestSubstring(self, s: str) -> int: d = {} i, j = 0, 0 ans = 0 while j
@SayXaNow6 ай бұрын
Эффективно только, если рассматривать с позиции лаконичности записи. У меня словарь тоже был первой идеей из-за возможности хранить индекс по ключу символа, но что-то меня смутило и в итоге быстро переделал через сет, почти 1 в 1 как у Саши с небольшой незначительной поправкой. Реализация со словарём конечно красива, и строчек кода на две меньше, ввиду отсутствия цикла удаления ненужных ключей, но перфоманс у неё хромает. Для лучшего случая по скорости на 20% хуже сета, в среднем в 2 раза медленнее, а для худшего случая решение со словарём медленнее почти в 4 раза. Это конечно все равно и тут, и там O(N), но такая разница немного удивила. Но не привыкать, в питоне не все то, что красивее выглядит, быстрее работает, зачастую как раз наоборот.
@yuriynicom6 ай бұрын
Без лишних слов, Превосходный контент и знания! СПАСИБО!!!! Вопрос: Английский вариант названия алгоритма "метод скользящего окна" ? The Sliding window ?
@kusdav1etov6 ай бұрын
Да
@heaven7pro6 ай бұрын
Это отличное объяснение, я серьёзно
@p4xt3r6 ай бұрын
Спасибо за видео! У меня появился вопрос касательно быстрого решения. В видео говорится, что скорость O(n), но ведь по сути мы используем два цикла, один из которых вложен. представим, что в функцию отдается строка из одинаковых символов и тогда во все итерации кроме первой будет падать во вложенный цикл. а на сколько я помню скорость считается исходя из худшего случая. Почему в этом случае скорость O(n)? буду очень благодарен за ответ!
@gadpetrovich6 ай бұрын
Если исходить из худшего случая, то и set можно выкинуть, т.к. он там по добавлению будет равен O(n), а не O(1).
@motya226 ай бұрын
Возник тот же вопрос, задал его chatGPT и он ответил, что "каждый символ строки рассматривается и обрабатывается один раз либо указателем right, либо указателем left.
@14bbb885 ай бұрын
У интерфейса Set, метод add и так делает проверку на наличие, можно лишний раз не вызывать contains. public static int longestSubstring(String in) { int max = 0; LinkedHashSet set = new LinkedHashSet(); for (char c : in.toCharArray()) { while (!set.add(c)) { max = Math.max(max, set.size()); set.removeFirst(); } } return Math.max(max, set.size()); }
@yerzhan_auyezov6 ай бұрын
Буду благодарен, если сделаете ролик с roadmap по алгоритмам и то какие задачи решать
@joyniferzagher98712 ай бұрын
Это кстати носит более распространенное название -- "метод двух указателей"
@igorpistolyakaify6 ай бұрын
Приветствую, во втором случае можно немного оптимизировать решение: предположим, что есть текущая уникальная подстрока и мы нашли следующий неуникальный символ, если размер "хвоста" меньше чем размер найденной подстроки, то можно прекратить поиск и вернуть результат. Очевидно, что выигрыш невелик, но все же.
@andreyzyablikov98916 ай бұрын
Подумав, решил методом похожим на скользящее окно, правда вместо указателей я бы воспользовался List(C#, System.Collections.Generic), но не уверен, что List подойдёт по оптимизации лучше и сопоставимо, чем указатели. Спасибо за видео.
@Победа-ш1з6 ай бұрын
Изначально пришёл 2 вариант на ум, до первого даже догадаться не смог. По времени заняло минуты 2-3.
@ДениПух6 ай бұрын
Хотелось бы больше примеров на Java ) спасибо 😊
@eduardtsuranov7125 ай бұрын
Быстрое решение вроде как упрощенно "два указателя"(не шарю в алгоритмах). Но мне показалось, что когда мы пришли к повтору, то нет нужды уменьшать окно, можно двигать вправо ОБА указателя одновременно, ведь нас не интересуют размеры подстрок меньше максимальной из уже найденных. Вопрос правда реализуемо ли это(эффективнее), т.к. второй пункт(сужение) выполняет задачу убрать дубль. Чтобы продемонстрировать логику, на питоне: def longest_substring(s): left = 0 for right in range(len(s)): if len(set(s[left: right + 1]))
@МаркХ-у9ь6 ай бұрын
Спасибо за видео! Можете пожалуйста посоветовать с чего начать изучение алгоритмов, если только только изучил основы python?
@michaelgolub20196 ай бұрын
Первое, что пришло в голову, это то, что Вы назвали "метод скользящего окна". Я бы, наверное, это писал на компилируемом языке, если бы такое было позволено.
@user-lk8n0fgjk6 ай бұрын
Отличное видео! Спасибо! Делай, пожалуйста, побольше такого контента на виды алгоритмов. И да, мы скучаем по Java)
@MrAsdimchik6 ай бұрын
Спасибо за видео. Какой инструмент используется для демонстрации ? Очень удобно отображать скрытый код при нажатии. Сам часто делаю тех презентации и такой инструмент очень бы сильно помог, а то ливкодинг глючит )))
@oArleo6 ай бұрын
Я бы построчным вводом добавлял , сортировал массив и сравнивал первую и вторую позиции и как только они равны записал бы размер массива-1, а потом начинал бы со второго символа.
@kirill_monster6 ай бұрын
3:30 можно обойтись без флага используя такой синтаксис: for bla bla bla: print('Стоп') break else: print('Цикл завершен без остановки')
@SEIREIII6 ай бұрын
Нормально, 24 задание ЕГЭ, поехали
@Mikhail_Zaitsev6 ай бұрын
элементарный алгоритм и первое что приходит в голову. Ну а первый вариант очевидно отвергается сразу. Я удивлён простотой.
@alexnilev77796 ай бұрын
не понял на 5:16 говорится "удаляем пока в подстроке нету повторяющихся символов", хотя указатель на left - С и в подстроке остается С, тоесть они указывают на одинаковый символ , почему его он не удаляется как все предыдущие?
@АндрейБочарников-х5ъ6 ай бұрын
это повторяющийся символ из предыдущей подстроки, с него будет начинаться новая подстрока
@bertzaza3 ай бұрын
Попалась такая на входных экзаменах на стажировку в тинек)
@nabamapo6 ай бұрын
Спасибо за видео! А что это за софт со спойлерами и где можно рисовать?
@MrKirTer6 ай бұрын
Спасибо! Эффективность ваших видео O(n)!
@Ermorder16 ай бұрын
Неплохое решение, но вот другое - за один проход, запоминая последний индекс символа. Swift: func lengthOfLongestSubstring(_ s: String) -> Int { var map: [Character: Int] = [:] var result = 0 var left = 0 for (i, c) in s.enumerated() { if let j = map[c] { left = max(left, j + 1) } result = max(result, i - left + 1) map[c] = i } return result }
@_M.i.h.a.i.l._6 ай бұрын
Попросил ИИ переписать на АХК скрипт +вернуть саму строку: lengthOfLongestSubstring(s, ByRef longestSubstring = ""){ map := {} result := 0 left := 0 longestSubstring := "" Loop, Parse, s { c := A_LoopField if (map.HasKey(c)) { left := Max(left, map[c] + 1) } result := Max(result, A_Index - left) map[c] := A_Index - 1 if result longestSubstring := SubStr(s, left, result) } } return result }
@CatBlack-p2h6 ай бұрын
на java public class LongestSubstringLength { public static int lengthOfLongestSubstring(String s) { HashMap map = new HashMap(); int result = 0; int left = 0; for (int i = 0; i < s.length(); i++) { char c = s.charAt(i); if (map.containsKey(c)) { left = Math.max(left, map.get(c) + 1); } result = Math.max(result, i - left + 1); map.put(c, i); } return result; }
@st.kevich6 ай бұрын
С мапой очень плохое решение. Используется доп память. И не забывайте о том как растет мапа - это тоже далеко не бесплатно.
@heybeachMIN6 ай бұрын
на питоне бы...
@Oldy5735 ай бұрын
@@st.kevichочень плохое решение в видео и растет оно Символов у тебя фиксированное количество в отличие от букв
@rasZam6 ай бұрын
спасибо, больше разборов задач. Не подскажете, что за второй монитор у вас?
@maxmoriss6 ай бұрын
Элегантное решение на Python, max_length = 0 left = 0 seen = {} for right, char in enumerate(s): if char in seen: left = max(left, seen[char] + 1) seen[char] = right max_length = max(max_length, right - left + 1) return max_length
@CorWinTheOrder6 ай бұрын
не сработает вот на этом примере "abcbad" я когда сам решал, тоже на этом моменте спотыкался
@vog256 ай бұрын
Крутое видео! А если не секрет - то чем занимаешься в гугле? Что за стек?
@furtherance60426 ай бұрын
Прикольно. Лайк. Я только погружаюсь в программирование. Будет ли полезно в первом цикле (где увеличиваем подстроку) не прогонять её по минимальным значениям а сразу увеличить на Макс. Длинну, уже записанную в сет? Так мы пропустим (в данном примере) проверку сетов cb и db.
@rof3leo6 ай бұрын
@furtherance6042 если я тебя правильно понял, то, если ты будешь пропускать символы, тогда сет не будет хранить все символы подстроки => ты можешь не понять, что случился повтор
@jagorrim23716 ай бұрын
Было бы интересно послушать про работу различных структур данных
@daniyarzhanakhmetov77416 ай бұрын
Крутецки всё объяснил! Спасибо!
@sinushkin22 күн бұрын
Вместо Set я бы использовал Map и хранил в значении индекс элемента который буду удалять, чтобы не пробегаться по циклу while
@Be3y4uuK0T6 ай бұрын
что-то я не понял, на 5:13 мы проверяем и удаляем символы, на которые указывает left, но в алгоритме на java на 7:53 мы проверяем в while символ, на который указывает right, а не left. почему так? объясните, пожалуйста
@griprudnikov43746 ай бұрын
Классное видео! А какой шрифт используется для кода?
@IgorAlov6 ай бұрын
Похож на courier new
@itananas6 ай бұрын
Очень крутое объяснение, спасибо!
@bobbob-rd7yz6 ай бұрын
можно просто 1 раз идти по масиву и добавлять колличество уникальних елементов до первого повоторения в новий масив, потом повторять подсчет с последнего уникального елемента, а потом просто взять наибольшое число нового масива.
@МихаилТихомиров-м8ч6 ай бұрын
Неплохое объяснение, но не оценивается вставка и поиск в Set, интервьювер разве не укажет на этот момент?
@emptyspaces40676 ай бұрын
Уже несколько подобных комментов тут. Что вы так ополчились на сэты, что плохого они вам сделали?
@МихаилТихомиров-м8ч6 ай бұрын
@@emptyspaces4067 "мы" это разные люди, я за себя говорю, мне стало интересно, потому что это вопрос на засыпку.
@SayXaNow6 ай бұрын
@@МихаилТихомиров-м8ч принято считать что работа с сетом это константа. адепты лога будут негодовать, но на деле, чтобы сет постоянно уходил в лог - это надо нехило так постараться. плюс надо точно знать, а что под капотом у данной конкретной реализации сета, вдруг там реально обычное дерево, а не хэшмап. обычно совмещают оба два сразу. ну а в данной задачке, если символы ограничены - то можно реализовать свой собственный сет, который будет абсолютной константой, к которой уже невозможно будет придраться.
@МихаилТихомиров-м8ч6 ай бұрын
@@SayXaNow ну вообще джавовский hashset это как раз О(1), насчет пайтона я не знаю. Просто это может быть вопрос на засыпку от интервьювера, стоит об этом помнить.
@heybeachMIN6 ай бұрын
@@МихаилТихомиров-м8ч у пайтона как я знаю тоже
@yerzhan_auyezov6 ай бұрын
Круто! Давно искал подобный канал с разборами задач, спасибо!
@preved396 ай бұрын
как все красиво и понятно, спасибо, Александр! Кстати, а где рисуется такая "интерактивная" анимация?
@_Katsuryoku_6 ай бұрын
Для первого варянта есть гораздо проще решение: def longest_substring(string: str ) -> int: lenght = 0 for i in range(len(string)): save = '' for j in string[i:]: if j not in save: save += j else: break if len(save) >= lenght: save = len(save) return lenght
@aidoka20006 ай бұрын
spasibo, Sasha za detalniy razbor.
@lesindorf-934videos6 ай бұрын
Цифры Пифагора. Если у треугольника длины сторон 3, 4 и 5 метров, то он -- прямоугольный. Или 6, 8 и 10 метров. И т. д. Эти волшебные цифры позволяют на местности рисовать прямые углы. Размечать местность под фундамент, например.
@АртемПотешкин-к6о6 ай бұрын
Привет! Было бы круто, если бы разобрал задачу Medium from two sorted arrays. Нигде не могу найти хорошого объяснения
@Isamatdin3 ай бұрын
есть способ в котором только r будет один раз пройтись по строке, этот код работает за O(n), а не O(2n). Но это почти ничего не меняет. def solve(n,s): ans=0 l,r=0,0 hash_mp={} while r
@ДмитрийМилосердов-и7п6 ай бұрын
Хочу поделиться своим решением, на момент ответа видео не досмотрел. Сравниваем элементы с помощью бинарного дерева. В цикле начинаем сравнивать , если элемент меньше идём в лево, если равно continue. Если след узел null то тогда записываем в дерево элемент и увеличиваем count ++. После цикла выводим count. У нас получится уникальное бинарное дерево, с счётчиком count.
@emptyspaces40676 ай бұрын
Очень интересно, но ничего не понятно. Можно код, желательно на жабе или питоне?
@saasrus6 ай бұрын
А проверка того что буква уже в сете за проверку не считается и проходит мгновенно?
@ДартРеван-ч7ь6 ай бұрын
Этот алгоритм напомнил мне метод указателей можно ли в данном случае его использовать?
@mrdastinol70076 ай бұрын
Насколько я понимаю, удаление с начала масива очень долгое, потому что нужно создать другой масив и перекопировать все значения в него. Поэтому, когда у нас будет очень длинная подстрока, придётся много раз пересоздавать масив внутри сета. Лучше уж после каждой итерации поставить проверку (result < right - left + 1). Но может сет в Java работает не так как я думаю, надеюсь на отзыв.
@oleksandr22346 ай бұрын
Не пересоздается сет после удаления слева. Если не удалять - то не будет работать contains().
@mrdastinol70076 ай бұрын
@@oleksandr2234 Спасибо за ответ!
@menceyh6 ай бұрын
Операции над set'ом же за ln(n) выполняются. Поэтому сложность с sliding window O(n*ln(n)), а без O(n^3 * ln(n))
@maximkutkov6 ай бұрын
он использовал unordered_set, где клюли хешируются за O(1)
@AlexanderSavchenko916 ай бұрын
спасибо интересный алгоритм!
@ДаниилГончаров-к7и6 ай бұрын
Если хотите получить быстрее решение, юзайте биты, 256 штук достаточно. Просто ставьте в 1 разряд номер символа в таблице асик. Хеш тут не нужен. К сожалению, не знаю как на джаве. Но на си это явно быстрые, чем хеш таблица
@SayXaNow6 ай бұрын
ты описал элементарный 32байтный хэш, в котором идеальная хэш-функция занимается вычислением нужного бита.
@user-iu1jl3km6 ай бұрын
Мне кажется что первый алгоритм выполняет не n в кубе операций , а (n+n*n) /2 так как right пробегает от i до n символа, где i - положение left; у второго алгоритма максимальная скорость O(n) , а минимальная O(n*n) потому что right точно пробежит один раз строку, а left может остаться в начале (если все символы разные) или пробежать все символы (если все символы одинаковы) P. S. Укажите если не прав
@Anonymous-65986 ай бұрын
Отличное видео! Спасибо!
@mirzomuminsobirjonov11046 ай бұрын
Поставил на паузу и попробовал такое решение со скоростью алгоритма O(n): def get_the_longest_substring(string): length = 0 left = 0 seen = {} for i in range(len(string)): char = string[i] if char in seen and seen[char] >= left: diff = i - left left = seen[char] + 1 if diff > length: length = diff seen[char] = i if left == 0: return len(string) return length
@rof3leo6 ай бұрын
а как же обращение к отображению за O(log(n)) в среднем?
@mirzomuminsobirjonov11046 ай бұрын
@@rof3leo что ты имеешь ввиду? можешь немного подробнее описать? или ты про объем памяти алгоритма спрашиваешь?
@SayXaNow6 ай бұрын
@@mirzomuminsobirjonov1104 ну многие думают, операции с сетами и словарями занимают лог времени. лично я по тестам вижу константу. кстати, твое решение через словарь медленнее, чем через сет почти в 2 раза. конечно это все равно будет линейная сложность, но в питоне похоже операции со словарем гораздо медленнее сетовых.
@mirzomuminsobirjonov11046 ай бұрын
@@SayXaNow возможно ты и прав, но при решении алгоритмов на собесе такое вряд ли рассматривают, так как это просто константа. это можно написать на компилируемом языке чтоб ускорить процесс по времени.
@vasilekx86 ай бұрын
Спасибо за видео! Немного запутанное объяснение либо такое ощущение, что какие-то кадры ошибочно вырезаны с видео. Либо плохо разобрался)
@sherumov64726 ай бұрын
Отличное видео, спасибо
@leomysky6 ай бұрын
Спасибо за видео, всё понятно
@MichailLLevin6 ай бұрын
а можно вместо set завести массив длинной в алфавит и держать в нем последний индекс, содержащий данную букву. Двигаем правый указатель, смотрим, была ли текущая буква в окне, если нет - запоминаем, идем дальше. Если буква была - стоп, проверяем, не больше ли текущее окно лучшего, если нашли лучшее - запоминаем окно и переставляем левый указатель сразу после буквы, которая повторилась. по сути - то же, но не надо двигать левый указатель по одному шагу, ну и обратиться к массиву - быстрее, чем добавлять-убирать из сета.
@jaggman21346 ай бұрын
Первая мысль такая же была, только не с алфавитом, а в общем случае - хэшмапой
@rof3leo6 ай бұрын
можно даже не индекс, а просто true, если встретилась и false, если нет. boolean меньше памяти занимает (хотя у тебя немного побыстрее работает). Потом в цикле проверяешь, если текущая буква уже встречалась, то двигаешь левый указатель, пока не уберешь предыдущее вхождение
@MichailLLevin6 ай бұрын
@@rof3leo тогда придется на каждом шаге отбегать до начала текущей последовательности?
@MichailLLevin6 ай бұрын
@@jaggman2134 честно говоря, у меня старая нелюбовь к хашмэпам, несколько раз сталкивался с тем, что сет на хэше работает в разы медленнее, чем обычный сет (вероятно на дереве). Если храним строки, получение хэша пробегает каждую строку до конца, а сравнение на < обычно кончается на первой же букве.
@ArtsiomShendzikau6 ай бұрын
Вы могли записать видео про метод двух указателей?
@kusdav1etov6 ай бұрын
Мне еще в голову пришло решение за O(nlogn) с помощью метода фиксированного скользящего окна и бинарного поиска)
@fedordostoevskiy42096 ай бұрын
Я думал что stack использовать нужно. 👍
@БатырбекАйгалиев6 ай бұрын
Очень крутое видео, спасибо!
@VictorVedmich6 ай бұрын
О а не подскажите через что вы делаете скрытие контента а потом его появление, по клику ?
@pythonForEvOne5 ай бұрын
подскажите что за приложение в котором вы стрелки по элементам так красиво двигали?
@niklegaloff6 ай бұрын
остановил на 2:07 и мне показалось что первое очевидное решение на самом деле сложное и неочевдиным, очевидным решением для меня пробежаться по всем символам с хэшсетом накапливая его и фиксируя максимальный результат при наличии символа уже в нём, при этом сбрасывая его и возвращаясь назад на величину r-1, сча посмотри какое решение предложит автор
@ergf-r6h5 ай бұрын
Саша, привет. По моему, второй цикл while не обязателен (хотя, скорее всего, он ускоряет программу)
@tonylayz6 ай бұрын
1. Непонятно зачем использовать set если мы можем пройтись по уже существующей строке 2. Удаление пока не пропадут все повторяющиеся символы? Если ты добавляешь 1 символ, то куда проще будет проверить повторяется ли этот символ и потом найти индекс первого вхождения и удалить все символы до него
@SayXaNow6 ай бұрын
Без сета ты улетишь в O(n*(n+1)/2) = O(n^2) по сложности для худшего случая.
@tonylayz6 ай бұрын
@@SayXaNow там и так O(n^2) из-за while
@SayXaNow6 ай бұрын
@@tonylayz тот while выполнится не более N раз за всю работу кода, следовательно его плюсуют к N, а не умножают на N. А твой проход выполнятся будет в среднем N/2 за каждую итерацию внешнего цикла, поэтому его умножают на N.