Первый Алгоритм Для Изучения в 2024

Поділитися
Вставка
  • Опубліковано 20 тра 2024
  • Разбираем алгоритм, который поможет решать задачи на собеседованиях в крупные айти компании.
    Подписывайтесь на мой Телеграм канал: t.me/saschalukin
    Эта задача на Leetcode: leetcode.com/problems/longest...
    00:00 Вступление
    00:23 Условие
    01:20 Решение перебором
    03:59 Быстрое решение
    06:37 Код

КОМЕНТАРІ • 299

  • @sashalukin
    @sashalukin  23 дні тому +7

    Создал Telegram канал, в котором рассказываю о работе в Google, подготовке к собеседованиям и жизни в Лондоне. Подписывайтесь: t.me/saschalukin

    • @manOfPlanetEarth
      @manOfPlanetEarth 20 днів тому +1

      Саша, сделай уже, плз, плейлисты на канале☝🏼☝🏼 С задачами, пр. и тд. Скомпонуй видосы.

    • @albertbrawls
      @albertbrawls 18 днів тому +1

      Оаоаао что это?! Метод двух указателей!

    • @boriskogan-lerner7485
      @boriskogan-lerner7485 8 днів тому

      Если правильно понимаю, в некоторых случаях операции с хешем могут стремиться к O(logN)=> общее время будет приближаться к O(N*logN). Где N- длинна строки т.к. операции выполняются дважды, а размер сета в худшем случае будет N/2 (Среднее членов арифметической прогрессии(An+A1)/2). 1/2*2=1
      П.с. Часа полтора потратил что бы понять что что-бы решит проблему коллизий при хешировании нам надо выделять примерно "очень много" памяти на каждый сет, установить жесткое ограничение в размере строки и используемом наборе символов а так же тратиться на сжать/разжать данные в этой строке

  • @sobirabdulxair9001
    @sobirabdulxair9001 22 дні тому +81

    один из редких каналов, где разбирают и объясняют по-человечески без лишнего пафоса. жду с нетерпением каждого разбора.

  • @mndevitmndevit
    @mndevitmndevit 22 дні тому +7

    Как же я долго ждал нового видео, спасибо тебе огромное! Вот бы они выходили чаще)

  • @kirillschcerbinin7068
    @kirillschcerbinin7068 21 день тому +3

    spasibo, Sasha za detalniy razbor. Видосы становятся все лучше и лучше по качеству, харош

  • @MrKryuk
    @MrKryuk 18 днів тому +2

    Саша, спасибо за разборы.
    Косательно этого решения догадался про указатель `right`, что нет смысла увеличивать его, но не догадался про перемещение left.

  • @kuroiumi9949
    @kuroiumi9949 19 днів тому

    Ура ура! С возвращением, Сань :)
    Круто что ты стал записывать видео чаще))

  • @heybeachMIN
    @heybeachMIN 16 днів тому

    Спасибо ОГРОМНОЕ за такой подробное объяснение, всё понятно теперь) Было бы круто увидеть подобное объяснение но про деревья))

  • @user-od1it3ru3o
    @user-od1it3ru3o 21 день тому +7

    Саша, привет!
    Спасибо за интересное видео. Единственное, ты слегка меня запутал когда сказал, что "удаляем, пока в сете есть повторяющиеся символы" - по факту, в сете они не повторяются. Наверное, лучше было бы сказать что удаляем, пока не удалим ПОВТОРИВШИЙСЯ символ)

  • @Swydk
    @Swydk 23 дні тому +2

    Привет, хотел выразить тебе огромное спасибо. Посмле просмотра видео про гугл и инжерена. Мне вернулся дух программиста. Начал вести фриланс и параллельно изучаю собесы

  • @badishow4807
    @badishow4807 23 дні тому +42

    На пробнике ЕГЭ подобная задача попадалась (24-е задание).
    Решил очень похожим способом
    Видео, как всегда, интересное. Благодарю за контент!

    • @user-vv3gg6xm1b
      @user-vv3gg6xm1b 22 дні тому +2

      тоже сдаю егэ, как раз захотел выучить алгоритм чтобы если что использовать) да и в целом полезная вещь

    • @romanpritkov1107
      @romanpritkov1107 15 днів тому

      но там тебе на сложность наплевать в егэ

  • @VDlasov
    @VDlasov 20 днів тому +1

    Было интересно изучить. Главное с апреля начать

  • @cablook_egja
    @cablook_egja 21 день тому +2

    простой перебор можно сократить и до 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
    Спасибо за видео

  • @Whispered__Wisdom
    @Whispered__Wisdom 22 дні тому +1

    Привет, пожалуста продолжай, очень полезно и информативно, сейчас активно пытаюсь прокачать алгоритмы и твои видосы прям то-что нужно!!!

  • @stas-web
    @stas-web 23 дні тому +1

    Спасибо, отличная подача. Без воды и смс. Успехов.

  • @aidoka2000
    @aidoka2000 23 дні тому

    spasibo, Sasha za detalniy razbor.

  • @panfilovandrey
    @panfilovandrey 19 днів тому +1

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

  • @auyezove
    @auyezove 21 день тому +1

    Круто! Давно искал подобный канал с разборами задач, спасибо!

  • @leomysky
    @leomysky 20 днів тому

    Спасибо за видео, всё понятно

  • @Anonymous-6598
    @Anonymous-6598 22 дні тому

    Отличное видео! Спасибо!

  • @daniyarzhanakhmetov7741
    @daniyarzhanakhmetov7741 5 днів тому

    Крутецки всё объяснил! Спасибо!

  • @itananas
    @itananas 14 днів тому

    Очень крутое объяснение, спасибо!

  • @user-lk8n0fgjk
    @user-lk8n0fgjk 22 дні тому +4

    Отличное видео! Спасибо! Делай, пожалуйста, побольше такого контента на виды алгоритмов. И да, мы скучаем по Java)

  • @kalts_daniil
    @kalts_daniil 23 дні тому +19

    Я только что решал задачу: Longest Substring Without Repeating Characters, и вуаля, тут видео на sliding window подъехало 🔥 Спасибо!

    • @ghostlynomad7788
      @ghostlynomad7788 22 дні тому +2

      Кстати на днях сидел решал эту задачу на leetcode , и она у меня не прошла последний тест из-за Time Limit Exceeded (986 / 987 testcases passed).
      Мой подход был такой - я собирал все уникальные подстроки (в отдельном методе я проверял что подстрока состоит из уникальных символов) в лист и затем с помощью компаратора сортировал по длине и возвращал длину последнего элемента

    • @user-yd9xy3rb4x
      @user-yd9xy3rb4x 22 дні тому

      Да просто алгосы везде одинаковые +-

    • @user-ut8bs1ku5e
      @user-ut8bs1ku5e 22 дні тому +4

      @@ghostlynomad7788 не мудрено, что по времени не прошел. Мало того, что собирал лист со сложностью n в квадрате, а то и n в кубе, так потом еще и добавил n*log(n) (я про сортировку). Ничего медленнее мне кажется тут уже не придумать))

    • @ghostlynomad7788
      @ghostlynomad7788 22 дні тому

      @@user-ut8bs1ku5e больше ни до чего не додумался ) и да, сложность сборки листа n в кубе🙈

    • @ghostlynomad7788
      @ghostlynomad7788 22 дні тому

      @@user-ut8bs1ku5e n в кубе на самом деле)
      но больше ни до чего не додумался за пару дней

  • @MrKirTer
    @MrKirTer 15 днів тому

    Спасибо! Эффективность ваших видео O(n)!

  • @user-ku2hc3mr3m
    @user-ku2hc3mr3m 23 дні тому

    Очень крутое видео, спасибо!

  • @rickgmv1844
    @rickgmv1844 21 день тому

    Спасибо за классное объяснение, а то я когда на литкоде пыхтел над этими задачами с окном, чуть мозг не сломал, разбирая этот алгоритм

  • @vladimira9360
    @vladimira9360 22 дні тому

    Приятно осознавать, что я бы решил подобным образом.

  • @flake1604
    @flake1604 22 дні тому +5

    За Иннополис за заднем фоне превью лайк)

  • @sherumov6472
    @sherumov6472 18 днів тому

    Отличное видео, спасибо

  • @heaven7pro
    @heaven7pro 14 днів тому +1

    Это отличное объяснение, я серьёзно

  • @AlexanderSavchenko91
    @AlexanderSavchenko91 18 днів тому

    спасибо интересный алгоритм!

  • @auyezove
    @auyezove 21 день тому

    Буду благодарен, если сделаете ролик с roadmap по алгоритмам и то какие задачи решать

  • @Lammax2012
    @Lammax2012 22 дні тому

    Кайф! Спасибо!

  • @jagorrim2371
    @jagorrim2371 22 дні тому

    Было бы интересно послушать про работу различных структур данных

  • @user-fh9dp6kg8o
    @user-fh9dp6kg8o 17 днів тому

    Хотелось бы больше примеров на Java ) спасибо 😊

  • @user-ey9xi9dq6l
    @user-ey9xi9dq6l 20 днів тому +3

    Изначально пришёл 2 вариант на ум, до первого даже догадаться не смог.
    По времени заняло минуты 2-3.

  • @suuron
    @suuron 15 днів тому +1

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

  • @staspanyukov4822
    @staspanyukov4822 18 днів тому

    спасибо за видео

  • @alexandreabramtsev9160
    @alexandreabramtsev9160 19 днів тому

    Я конечно дико извиняюсь, но это круто и изящно! Придумал на лету тоже вариант O(n), но он немного сложнее и кушает больше памяти - на каждый индекс массива создавать отдельный сет и добавлять в него пока "дубль" символа не встретится. Метод скользящего окна намного красивее!

  • @user-ut8bs1ku5e
    @user-ut8bs1ku5e 22 дні тому

    Спасибо за видео! Сам около года назад сидел плотно в литкоде, задачи на скользящее окно были одними из любимых) Увидел условие, решил проверить сам себя, решу ли ее сейчас. Минут за 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

    • @rof3leo
      @rof3leo 22 дні тому

      какая асимптотика?

    • @user-ut8bs1ku5e
      @user-ut8bs1ku5e 16 днів тому

      @@rof3leo O(n) по времени и памяти

  • @ArtsiomShendzikau
    @ArtsiomShendzikau 20 днів тому

    Спасибо за видео! Какие еще задачи можно решать методом скользящего окна?

  • @andreyzyablikov9891
    @andreyzyablikov9891 21 день тому

    Подумав, решил методом похожим на скользящее окно, правда вместо указателей я бы воспользовался List(C#, System.Collections.Generic), но не уверен, что List подойдёт по оптимизации лучше и сопоставимо, чем указатели.
    Спасибо за видео.

  • @vog25
    @vog25 22 дні тому +1

    Крутое видео! А если не секрет - то чем занимаешься в гугле? Что за стек?

  • @kirill_monster
    @kirill_monster 23 дні тому +1

    3:30 можно обойтись без флага используя такой синтаксис:
    for bla bla bla:
    print('Стоп')
    break
    else:
    print('Цикл завершен без остановки')

  • @user-cs7uk1fe4v
    @user-cs7uk1fe4v 20 днів тому +1

    Первый раз за 10 лет в айти нашел нормально объясняющего на русском человека. Мне это конечно не пригодится, но было интересно 👍

  • @MrAsdimchik
    @MrAsdimchik 18 днів тому

    Спасибо за видео.
    Какой инструмент используется для демонстрации ? Очень удобно отображать скрытый код при нажатии. Сам часто делаю тех презентации и такой инструмент очень бы сильно помог, а то ливкодинг глючит )))

  • @arthur.v.babayan
    @arthur.v.babayan 17 днів тому

    Интересно, конечно :)

  • @user-xx1ek4ct7c
    @user-xx1ek4ct7c 20 днів тому

    Спасибо за видео! Можете пожалуйста посоветовать с чего начать изучение алгоритмов, если только только изучил основы python?

  • @rasZam
    @rasZam 23 дні тому

    спасибо, больше разборов задач. Не подскажете, что за второй монитор у вас?

  • @nabamapo
    @nabamapo 23 дні тому +1

    Спасибо за видео! А что это за софт со спойлерами и где можно рисовать?

  • @borys7837
    @borys7837 22 дні тому +6

    Избыточность в расчете answer. Его стоит пересчитывать в случае повторения буквы и последний раз когда заканчиваем всю функцию.

    • @crimfi
      @crimfi 22 дні тому +1

      На асимптотику это не влияет, + можно написать контртест для которого пересчёт все равно будет происходить на каждом шаге

    • @AlexanderRadchenko
      @AlexanderRadchenko 22 дні тому

      Да и ещё можно оптимизировать удаление из множества. Там не нужен поиск в множестве, достаточно простого сравнения символов.

    • @TurboGamasek228
      @TurboGamasek228 21 день тому

      @@crimfi на асимптотику не влияет, а на константу влияет

    • @crimfi
      @crimfi 20 днів тому

      @@TurboGamasek228 можно написать тест, для которого константа не изменится, при оценке рассматриваем худший случай

  • @andreyradostny
    @andreyradostny 23 дні тому

    🔥

  • @yuriynicom
    @yuriynicom 23 дні тому +1

    Без лишних слов, Превосходный контент и знания! СПАСИБО!!!! Вопрос: Английский вариант названия алгоритма "метод скользящего окна" ? The Sliding window ?

  • @artemkashipov9865
    @artemkashipov9865 22 дні тому +3

    по моему алгоритм можно улучшить используя bitset для хранения мапы элементов и то сколько раз они встретились

  • @user-vm9cs6vt1q
    @user-vm9cs6vt1q 15 днів тому

    Этот алгоритм напомнил мне метод указателей можно ли в данном случае его использовать?

  • @igorpistolyakaify
    @igorpistolyakaify 18 днів тому

    Приветствую, во втором случае можно немного оптимизировать решение: предположим, что есть текущая уникальная подстрока и мы нашли следующий неуникальный символ, если размер "хвоста" меньше чем размер найденной подстроки, то можно прекратить поиск и вернуть результат. Очевидно, что выигрыш невелик, но все же.

  • @Ermorder1
    @Ermorder1 21 день тому +8

    Неплохое решение, но вот другое - за один проход, запоминая последний индекс символа. 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._
      @_M.i.h.a.i.l._ 20 днів тому

      Попросил ИИ переписать на АХК скрипт +вернуть саму строку:
      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
      }

    • @user-zo5gt9ck9b
      @user-zo5gt9ck9b 18 днів тому +1

      на 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.kevich
      @st.kevich 17 днів тому

      С мапой очень плохое решение. Используется доп память. И не забывайте о том как растет мапа - это тоже далеко не бесплатно.

    • @heybeachMIN
      @heybeachMIN 16 днів тому +1

      на питоне бы...

  • @vasilekx8
    @vasilekx8 22 дні тому

    Спасибо за видео!
    Немного запутанное объяснение либо такое ощущение, что какие-то кадры ошибочно вырезаны с видео. Либо плохо разобрался)

  • @_AbUser
    @_AbUser 22 дні тому +1

    Клевый способ. А можно подгонкой размеров окна подобным способом находить всякие локальные максимумы, точки перегиба и прочее на каком ть временном ряде? По скольку они там формируются в вообще произвольной периодичностью.. ))) Было бы как раз...

  • @Be3y4uuK0T
    @Be3y4uuK0T 21 день тому +2

    что-то я не понял, на 5:13 мы проверяем и удаляем символы, на которые указывает left, но в алгоритме на java на 7:53 мы проверяем в while символ, на который указывает right, а не left. почему так? объясните, пожалуйста

  • @vitalylesindorf640
    @vitalylesindorf640 21 день тому

    Цифры Пифагора. Если у треугольника длины сторон 3, 4 и 5 метров, то он -- прямоугольный. Или 6, 8 и 10 метров. И т. д. Эти волшебные цифры позволяют на местности рисовать прямые углы. Размечать местность под фундамент, например.

  • @ivankondratyev2363
    @ivankondratyev2363 4 дні тому

    реализация "простого" решения убила... я даже и не подумал что так можно XD

  • @furtherance6042
    @furtherance6042 22 дні тому

    Прикольно. Лайк.
    Я только погружаюсь в программирование.
    Будет ли полезно в первом цикле (где увеличиваем подстроку) не прогонять её по минимальным значениям а сразу увеличить на Макс. Длинну, уже записанную в сет? Так мы пропустим (в данном примере) проверку сетов cb и db.

    • @rof3leo
      @rof3leo 22 дні тому

      @furtherance6042 если я тебя правильно понял, то, если ты будешь пропускать символы, тогда сет не будет хранить все символы подстроки => ты можешь не понять, что случился повтор

  • @bobbob-rd7yz
    @bobbob-rd7yz 2 дні тому

    можно просто 1 раз идти по масиву и добавлять колличество уникальних елементов до первого повоторения в новий масив, потом повторять подсчет с последнего уникального елемента, а потом просто взять наибольшое число нового масива.

  • @oArleo
    @oArleo 3 дні тому

    Я бы построчным вводом добавлял , сортировал массив и сравнивал первую и вторую позиции и как только они равны записал бы размер массива-1, а потом начинал бы со второго символа.

  • @takedaheroku
    @takedaheroku 19 днів тому

    Лайк👍

  • @user-jv6sq3mz3b
    @user-jv6sq3mz3b 20 днів тому

    Привет! Было бы круто, если бы разобрал задачу Medium from two sorted arrays. Нигде не могу найти хорошого объяснения

  • @saasrus
    @saasrus 20 днів тому +2

    А проверка того что буква уже в сете за проверку не считается и проходит мгновенно?

  • @thayornwarrior2785
    @thayornwarrior2785 22 дні тому

    красавчик

  • @kiminomeha
    @kiminomeha 20 днів тому

    О да, это очень классный алгоритм. Его еще называют методом двух указателей. Все, кто к ЕГЭ по информатике готовится, учат его, довольно эффективный и гибкий алгоритм

  • @michaelgolub2019
    @michaelgolub2019 15 днів тому

    Первое, что пришло в голову, это то, что Вы назвали "метод скользящего окна". Я бы, наверное, это писал на компилируемом языке, если бы такое было позволено.

  • @nullptr111
    @nullptr111 17 днів тому

    Как насчёт хэш-сета + рекурсия или это тоже будет давать O(n^2) или O(n^3)?

  • @fedordostoevskiy4209
    @fedordostoevskiy4209 22 дні тому

    Я думал что stack использовать нужно. 👍

  • @VictorVedmich
    @VictorVedmich 10 днів тому

    О а не подскажите через что вы делаете скрытие контента а потом его появление, по клику ?

  • @maxmoriss
    @maxmoriss 20 днів тому

    Элегантное решение на 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

    • @CorWinTheOrder
      @CorWinTheOrder 10 днів тому

      не сработает вот на этом примере "abcbad"
      я когда сам решал, тоже на этом моменте спотыкался

  • @SEIREI_MUSIC
    @SEIREI_MUSIC 15 днів тому +1

    Нормально, 24 задание ЕГЭ, поехали

  • @ArtsiomShendzikau
    @ArtsiomShendzikau 20 днів тому

    Вы могли записать видео про метод двух указателей?

  • @yevhenpetrunkin8071
    @yevhenpetrunkin8071 16 днів тому

    На JS:
    function getLongestUniqueLength (string) {
    let length = 0;
    let arr = [...string.split('')];
    let intermArr = [];
    for (let item of arr) {
    if (intermArr.includes(item)) intermArr.splice(0, intermArr.indexOf(item) + 1);
    intermArr.push(item);
    if (intermArr.length > length) length = intermArr.length;
    }
    return length;
    }

  • @alexnilev7779
    @alexnilev7779 22 дні тому +3

    не понял на 5:16 говорится "удаляем пока в подстроке нету повторяющихся символов", хотя указатель на left - С и в подстроке остается С, тоесть они указывают на одинаковый символ , почему его он не удаляется как все предыдущие?

    • @user-iq9ll8lz9m
      @user-iq9ll8lz9m 22 дні тому

      это повторяющийся символ из предыдущей подстроки, с него будет начинаться новая подстрока

  • @griprudnikov4374
    @griprudnikov4374 23 дні тому

    Классное видео! А какой шрифт используется для кода?

    • @IgorAlov
      @IgorAlov 22 дні тому

      Похож на courier new

  • @user-yy4lm3zd6c
    @user-yy4lm3zd6c 19 днів тому

    Хочу поделиться своим решением, на момент ответа видео не досмотрел.
    Сравниваем элементы с помощью бинарного дерева.
    В цикле начинаем сравнивать , если элемент меньше идём в лево, если равно continue. Если след узел null то тогда записываем в дерево элемент и увеличиваем count ++.
    После цикла выводим count.
    У нас получится уникальное бинарное дерево, с счётчиком count.

    • @emptyspaces4067
      @emptyspaces4067 19 днів тому

      Очень интересно, но ничего не понятно. Можно код, желательно на жабе или питоне?

  • @mirzomuminsobirjonov1104
    @mirzomuminsobirjonov1104 22 дні тому

    Поставил на паузу и попробовал такое решение со скоростью алгоритма 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

    • @rof3leo
      @rof3leo 22 дні тому

      а как же обращение к отображению за O(log(n)) в среднем?

    • @mirzomuminsobirjonov1104
      @mirzomuminsobirjonov1104 21 день тому

      @@rof3leo что ты имеешь ввиду? можешь немного подробнее описать? или ты про объем памяти алгоритма спрашиваешь?

    • @SayXaNow
      @SayXaNow 19 днів тому

      ​@@mirzomuminsobirjonov1104 ну многие думают, операции с сетами и словарями занимают лог времени. лично я по тестам вижу константу. кстати, твое решение через словарь медленнее, чем через сет почти в 2 раза. конечно это все равно будет линейная сложность, но в питоне похоже операции со словарем гораздо медленнее сетовых.

    • @mirzomuminsobirjonov1104
      @mirzomuminsobirjonov1104 18 днів тому

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

  • @vyacheslavs5642
    @vyacheslavs5642 15 днів тому

    В чём ты создаёшь свои анимации?

  • @xtxrnvl
    @xtxrnvl 14 днів тому

    Заметил Университет Иннополис на превью)
    Это просто случайность или ты как-то с ним связан?)
    я там первачок если что)

  • @menceyh
    @menceyh 18 днів тому

    Операции над set'ом же за ln(n) выполняются. Поэтому сложность с sliding window O(n*ln(n)), а без O(n^3 * ln(n))

    • @maximkutkov
      @maximkutkov 18 днів тому

      он использовал unordered_set, где клюли хешируются за O(1)

  • @p4xt3r
    @p4xt3r 15 днів тому +2

    Спасибо за видео! У меня появился вопрос касательно быстрого решения. В видео говорится, что скорость O(n), но ведь по сути мы используем два цикла, один из которых вложен. представим, что в функцию отдается строка из одинаковых символов и тогда во все итерации кроме первой будет падать во вложенный цикл. а на сколько я помню скорость считается исходя из худшего случая. Почему в этом случае скорость O(n)? буду очень благодарен за ответ!

    • @gadpetrovich
      @gadpetrovich 15 днів тому +1

      Если исходить из худшего случая, то и set можно выкинуть, т.к. он там по добавлению будет равен O(n), а не O(1).

    • @motya22
      @motya22 22 години тому

      Возник тот же вопрос, задал его chatGPT и он ответил, что "каждый символ строки рассматривается и обрабатывается один раз либо указателем right, либо указателем left.

  • @appngo6374
    @appngo6374 11 годин тому

    Я на практике редко пользуюсь конструкцией 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)
    }

  • @user-sg1ns5vx1m
    @user-sg1ns5vx1m 21 день тому

    Cпасибо большое, но в медленном алгоритме благодаря break внутренний цикл выполняется не более 26 раз, поэтому решение всё-таки за квадрат.

  • @niklegaloff
    @niklegaloff 22 дні тому +1

    остановил на 2:07 и мне показалось что первое очевидное решение на самом деле сложное и неочевдиным, очевидным решением для меня пробежаться по всем символам с хэшсетом накапливая его и фиксируя максимальный результат при наличии символа уже в нём, при этом сбрасывая его и возвращаясь назад на величину r-1, сча посмотри какое решение предложит автор

  • @user-hg4ni3kr6f
    @user-hg4ni3kr6f 19 днів тому +2

    Неплохое объяснение, но не оценивается вставка и поиск в Set, интервьювер разве не укажет на этот момент?

    • @emptyspaces4067
      @emptyspaces4067 19 днів тому

      Уже несколько подобных комментов тут. Что вы так ополчились на сэты, что плохого они вам сделали?

    • @user-hg4ni3kr6f
      @user-hg4ni3kr6f 19 днів тому

      @@emptyspaces4067 "мы" это разные люди, я за себя говорю, мне стало интересно, потому что это вопрос на засыпку.

    • @SayXaNow
      @SayXaNow 19 днів тому

      @@user-hg4ni3kr6f принято считать что работа с сетом это константа. адепты лога будут негодовать, но на деле, чтобы сет постоянно уходил в лог - это надо нехило так постараться. плюс надо точно знать, а что под капотом у данной конкретной реализации сета, вдруг там реально обычное дерево, а не хэшмап. обычно совмещают оба два сразу. ну а в данной задачке, если символы ограничены - то можно реализовать свой собственный сет, который будет абсолютной константой, к которой уже невозможно будет придраться.

    • @user-hg4ni3kr6f
      @user-hg4ni3kr6f 18 днів тому

      @@SayXaNow ну вообще джавовский hashset это как раз О(1), насчет пайтона я не знаю. Просто это может быть вопрос на засыпку от интервьювера, стоит об этом помнить.

    • @heybeachMIN
      @heybeachMIN 16 днів тому

      @@user-hg4ni3kr6f у пайтона как я знаю тоже

  • @eduardmart1237
    @eduardmart1237 20 днів тому

    А при помощи чего ты делаешь такие презентации? Ну когда кликаешь мышкой на квадрат и там открываются значения.

  • @_Katsuryoku_
    @_Katsuryoku_ 19 днів тому

    Для первого варянта есть гораздо проще решение:
    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

  • @gopnikkasarj6797
    @gopnikkasarj6797 22 дні тому

    А если в начале строки будет самая длинная строка, а потом она измениться, то что тогда?

  • @marcelodavid7035
    @marcelodavid7035 21 день тому

    А поиск символа в сете не учитывается в асимптотике?

  • @user-iu1jl3km
    @user-iu1jl3km 17 днів тому

    Мне кажется что первый алгоритм выполняет не n в кубе операций , а (n+n*n) /2 так как right пробегает от i до n символа, где i - положение left; у второго алгоритма максимальная скорость O(n) , а минимальная O(n*n) потому что right точно пробежит один раз строку, а left может остаться в начале (если все символы разные) или пробежать все символы (если все символы одинаковы) P. S. Укажите если не прав

  • @user-ze3ez3iy6c
    @user-ze3ez3iy6c 19 днів тому

    Я сразу додумался до решения

  • @alung414
    @alung414 13 днів тому

    Интересно, что этот алгоритм начали спрашивать сейчас. Решал его еще года 3-4 на леткоде тогда он мне попался где-то 5 по счету. То что додумался до решения сам конечно тешет мое самолюбие. Но вот то что часа полтора два у меня ушло чтобы выдать рабочий код на go нет).

  • @preved39
    @preved39 11 днів тому

    как все красиво и понятно, спасибо, Александр! Кстати, а где рисуется такая "интерактивная" анимация?

  • @MichailLLevin
    @MichailLLevin 22 дні тому

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

    • @jaggman2134
      @jaggman2134 22 дні тому

      Первая мысль такая же была, только не с алфавитом, а в общем случае - хэшмапой

    • @rof3leo
      @rof3leo 22 дні тому

      можно даже не индекс, а просто true, если встретилась и false, если нет. boolean меньше памяти занимает (хотя у тебя немного побыстрее работает). Потом в цикле проверяешь, если текущая буква уже встречалась, то двигаешь левый указатель, пока не уберешь предыдущее вхождение

    • @MichailLLevin
      @MichailLLevin 20 днів тому

      @@rof3leo тогда придется на каждом шаге отбегать до начала текущей последовательности?

    • @MichailLLevin
      @MichailLLevin 20 днів тому

      @@jaggman2134 честно говоря, у меня старая нелюбовь к хашмэпам, несколько раз сталкивался с тем, что сет на хэше работает в разы медленнее, чем обычный сет (вероятно на дереве). Если храним строки, получение хэша пробегает каждую строку до конца, а сравнение на < обычно кончается на первой же букве.

  • @sb-dor
    @sb-dor 23 дні тому

    Ребят решил вот таким способом, что думаете ? Про память да, переборщил наверное:
    int testAlg(String value) {
    int maxLength = 0;
    Map map = {};
    for (int i = 0; i < value.length; i++) {
    map[value[i]] = value[i];
    for (int j = i + 1; j < value.length; j++) {
    if (map.containsKey(value[j])) {
    maxLength = maxLength >= map.length ? maxLength : map.length;
    map.clear();
    break;
    } else {
    map[value[j]] = value[j];
    }
    }
    }
    return maxLength;
    }
    PS: мог бы использовать Set вместо Map