Задача из Собеседования в Amazon за 5 минут

Поділитися
Вставка
  • Опубліковано 7 тра 2023
  • Разбираем небольшую задачку, которую спросили на собеседовании в Amazon. Такие задачи надо уметь решать за 10-15 минут, но без опыта решения подобных задач найти самое быстрое решение может быть не просто.
    Задача на литкоде: leetcode.com/problems/search-...
    Пост на литкоде: leetcode.com/discuss/intervie...
    Дисклеймер:
    И задача, и пост на литкоде находятся в открытом доступе. Я к посту никакого отношения не имею и не могу гарантировать его правдивость.

КОМЕНТАРІ • 963

  • @sashalukin
    @sashalukin  2 місяці тому

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

  • @user-rv7jy5tv2n
    @user-rv7jy5tv2n Рік тому +172

    На собеседовании в амазон:
    -Вы умеете не ходить в туалет 12 часов?
    -Да
    -Вы приняты.

    • @and7770999
      @and7770999 Рік тому +30

      На собеседовании в ЕА Games
      - Вы радикальная феминистка?
      - Да
      - Вы приняты.

  • @lockstock5357
    @lockstock5357 Рік тому +307

    После того когда находишь более менее краткий путь к нужному результату всегда так на душе приятно становится. Внутренний перфекционист удовлетворен.

    • @igor_yanovich
      @igor_yanovich Рік тому +9

      Неприятно только одно, чтобы найти этот краткий путь, пришлось перебрать все пути не краткие 🤣

    • @user-ib1et9fi3p
      @user-ib1et9fi3p Рік тому +16

      И всегда найдётся азиат, который сделает это быстрее и лучше)

    • @and7770999
      @and7770999 Рік тому

      Только под массовость такое решение не подойдет. А значит придется писать отдельный код под разные матрицы

    • @and7770999
      @and7770999 Рік тому

      Самый лучший путь решения - отдать любому индусу на аутсорс))

    • @philipp4631
      @philipp4631 Рік тому

      5:10 ну как так-то хоть бы на словах надо было метод золотого сечения упомянуть да и вообще можно тупо делить пополам.

  • @igor_yanovich
    @igor_yanovich Рік тому +196

    Все эти задачки мне почему-то напомнили как один парень у нас в универе сдавал зачёты, подходил к одному спрашивал что спрашивает препод, потом к другому, потом к третьему, в общем так он перебирал абсолютно все варианты что спрашивал препод по конкретной лабе и потом сдавал её.
    Но стоило преподу однажды перед ним поставить новую задачу, которую он никогда ни у одного студента не спрашивал, как всё хорошее и закончилось.

    • @andrewmurruvyov4359
      @andrewmurruvyov4359 Рік тому +33

      Вероятность появления такой пары оригинальных (преподаватель;вопрос) мала, поэтому метод опроса надежен

    • @igor_yanovich
      @igor_yanovich Рік тому +21

      @@andrewmurruvyov4359 Это я к тому, что нафига вообще рассматривать методы решения задач, ну вот знаете вы как решить эту конкретную задачу в гугл на миллион долларов в год, а дай вам новую как всё хорошее и закончится, и нифига вы её уже не решите, потому что вы как этот парень из универа, вместо того чтобы учиться решать самому, тупо спрашивал у всех и перебирал все возможные варианты, а сам решать так и не научился, надо учится самому решать, а не смотреть на решения других людей и думать что теперь я мега умный и сам смогу решить такую задачу.
      Как говорится: всё просто когда знаешь как, а если не знаешь, то и таблица умножения кажется мега сложной задачей.

    • @andrewmurruvyov4359
      @andrewmurruvyov4359 Рік тому +72

      Экзамен сдаёт не тот кто умеет решать, а кто умеет сдавать, и на работу устраивается не тот кто может работать, а кто может проходить интервью

    • @igor_yanovich
      @igor_yanovich Рік тому

      @@andrewmurruvyov4359 как правило такие говноработники которые не умеют работать, а умеют устраиваться, потом долго не работают. потому что потом уже НАДО РАБОТАТЬ, а не сдавать 🤣🤣🤣

    • @user-wo4pr7vj2b
      @user-wo4pr7vj2b Рік тому +2

      @@andrewmurruvyov4359 а как этому научиться, если ты бездарь?

  • @kirillschcerbinin7068
    @kirillschcerbinin7068 Рік тому +8

    как всегда кайф смотреть, хорошо сделано! подача отличная, даже я всё понял, не зная ничего об этом! давай еще и побольше лайв контента!)

  • @zemamba
    @zemamba Рік тому +5

    Александр, крутые видео, записывай ещё ) интересно было бы про все этапы собеседования услышать в одном ролике

  • @andreyradostny
    @andreyradostny Рік тому +25

    Такая чистая, приятная и понятная подача, спасибо!

  • @baksonyan4ik
    @baksonyan4ik Рік тому +9

    Офигеть, до твоих видео вообще не решал алгоритмы и оказывается они намного легче чем я думал. Да и это видео просто change my mind

    • @freedomtv2295
      @freedomtv2295 Рік тому +16

      Когда объяснение под рукой то кажется легче, чем есть на самом деле
      На самом деле самому решать не так легко

    • @Gribozhuy
      @Gribozhuy Рік тому +3

      А что забавнее, что эти задачи мало кто решает так изящно сам по себе, фактически все учат только принципы и шаблоны, которых не так много. Это большой труд, но как это помогает определить хорошего программиста - вопрос :)

    • @baksonyan4ik
      @baksonyan4ik Рік тому

      @@Gribozhuy не программисту будет лень

    • @user-hi5fy6wv5j
      @user-hi5fy6wv5j Рік тому

      @@Gribozhuy, всё зависит от того, для решения каких задач нужен программист. Хороший программист для одних, ужасен для других.
      Скажем, задача та же, только у в распоряжении лишь три регистра и только один из них имеет ёмкость достаточную для указания на ячейку в матрице, при этом никто не лимитирует алгоритм по времени.
      Практическое применение: микроконтроллер без ОЗУ, все прочие регистры заняты другими данными всей микропрограммы, а её частью является алгоритм, микроконтроллер может 16 MIPS, а управляет дверным замком (то есть, даже если на сравнение уйдёт 30000 выполненных операций для матрицы 6*7, то это всего лишь задержка 0,001875 секунды, что человек в принципе не в состоянии заметить, да и замок открываться в следствии наличия инерции засова всё равно будет открываться дольше). И написать надо всё естественно на ассемблере.
      Так что, да, очень актуальен вопрос - как определить хорошего программиста?

  • @sunrizz
    @sunrizz Рік тому +4

    Удивительно, но почему то сразу пришел к такому решения 😮 Задача крута! Спасибо!

  • @vasiliypupkin6311
    @vasiliypupkin6311 Рік тому +3

    ❤ хоть у тебя и мало разборов, но они очень информативные, может будет хотя бы по 3 задачи в неделю - контент мега полезный, особенно для джунов. В Яндексе дают похожие.

  • @goldstein1
    @goldstein1 Рік тому +4

    С возвращением, Саша. Так мало качественных разборов нынче!

  • @Vitek_23
    @Vitek_23 Рік тому +1

    До такого решения не додумался бы сам, по крайней мере за 10 минут. Спасибо за пример!

  • @natielsanti407
    @natielsanti407 Рік тому

    Спасибо. С нетерпением жду следующего разбора.

  • @kpa3uk
    @kpa3uk Рік тому +3

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

    • @Morideca
      @Morideca Рік тому

      Ну, прописать 4 алгоритма для старта с каждого угла. И выбирать угол в зависимости от этого числа. Но это лишний гемор)
      ТЕм более что условие задачи поставило конкретное число, а не рандомное

  • @yjrus1807
    @yjrus1807 Рік тому +50

    Блин, это так просто и так гениально... мне стыдно, что я не додумался до такого решения сам

    • @noki1614
      @noki1614 Рік тому

      жиза

    • @alexanders8928
      @alexanders8928 Рік тому

      ты просто всю жизь не курил и не бухал и мухоморы не жевал. А Бог - есть!

    • @AwakenDrow
      @AwakenDrow Рік тому +1

      @@alexanders8928 Обычно, когда вспоминаешь все мухоморные дела, ты уже сеньор))

    • @and7770999
      @and7770999 Рік тому +1

      Еще проще решение - копируешь цифры в чат gpt и просишь его найти нужное))

    • @opusmode
      @opusmode Рік тому

      Это вообще не гениально. Это очень даже тупо.

  • @gobpblueex
    @gobpblueex Рік тому

    Красиво! Спасибо за разбор, все четко и по делу.

  • @GlebNite
    @GlebNite Рік тому +1

    Классное решение! Побольше таких видео :)

  • @fallerviktor
    @fallerviktor Рік тому +8

    А если взять 1 число - середину матрицы, и смотреть если число меньше 14 смотреть правое и снизу; дальше выбирать то, которое больше 14 и меньше второго? И двигаться таким полукрестом. Как скорость оценить?

    • @chalex2k
      @chalex2k Рік тому +1

      А идея хорошая, если это правильный алгоритм, сложность будет log(n+m). По сути бинпоиск по диагонали

  • @Nikolas_Z
    @Nikolas_Z Рік тому +21

    Я в целом решил таким же образом, только начинал с левого верхнего угла и не считаю, что этот метод менее эффективен. Просто в данном случае, у нас 4 столбца с числами меньше 14 и 2 с числами больше 14,но возможна и обратная ситуация

    • @The14Some1
      @The14Some1 Рік тому

      опиши алгоритм

    • @user-jc6fo7gf4w
      @user-jc6fo7gf4w Рік тому +10

      При k=5 выгоднее начинать с левого верхнего угла, а при k=24 выгоднее начинать с правого нижнего угла.
      Поэтому начинают с середины, как в обычном бинарном поиске: либо с правого верхнего угла, либо с левого нижнего угла.

    • @Magicrafter
      @Magicrafter Рік тому

      @@user-jc6fo7gf4w Мне показалось правильными начинать с правого нижнего. Ну то есть если бы мне дали 5 минут подумать, то мой вариант был бы таким. Хоть и не оптимальный.

    • @user-hi5fy6wv5j
      @user-hi5fy6wv5j Рік тому

      Левый верхний менее эффективен, нужно откатываться назад на 1 столбец упираясь в большее в следующем. Двигаться будем не по прямой (приближенной к прямой "траектории"), а "зигзагами".
      Представьте, что это не просто матрица, а пиксели на дисплее и каждая ваша выборка данных из матрицы закрашивает пиксель, увидите траекторию.

    • @AHTOHMAK
      @AHTOHMAK Рік тому +1

      Я тоже не понял разницы начинать именно справа

  • @progressiveaccount3270
    @progressiveaccount3270 Рік тому +1

    Отличный формат!

  • @ILikeActions
    @ILikeActions Рік тому +1

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

  • @ildarfattahov6441
    @ildarfattahov6441 Рік тому +34

    Спасибо за задачу. Кажется, что если на каждой строке или столбце, по которым мы передвигались из верхнего правого угла до 14, сделать бинарный поиск, то можно получить что-то около logN + logM

    • @denisgluk431
      @denisgluk431 Рік тому

      помойму можно матрицу намутить, в который ты больше одного шага по прямой не сможешь сделать

    • @nester7315
      @nester7315 Рік тому +2

      А зачем бинарный поиск? Мы по порядку идём. Он на больших массивах только замедлит.

    • @and7770999
      @and7770999 Рік тому

      А если матрица с рандомными числами будет? Придется переделывать

    • @oleksiikolotylenko1004
      @oleksiikolotylenko1004 Рік тому

      Ага)

    • @dmytrozazulin1858
      @dmytrozazulin1858 Рік тому

      Тоже возникла такая мысль. По сути, он для каждой строки ищет число, которое было бы меньше N, чтобы по этому столбцу далее найти число, котоое было бы больше N. И снова по строке, по столбцу и т.д.

  • @gorikan1h
    @gorikan1h Рік тому +6

    Отлично, первая же идея была довольно близка. Осталось самую малость, научиться кодить 😅

  • @DenisLyamets
    @DenisLyamets Рік тому

    Просто и при этом очень круто! Спасибо!

  • @iGeen7
    @iGeen7 Рік тому +2

    с какого перепугу O(n+m) это оптимальное решение?

  • @user-in9pm4sg6x
    @user-in9pm4sg6x Рік тому +3

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

    • @denisgluk431
      @denisgluk431 Рік тому

      Пойму тут O(n) получается, т.е. максимальный путь 2n.. меньше не придумаешь

    • @user-ly8ow7jg7u
      @user-ly8ow7jg7u Рік тому

      @@denisgluk431 В этом алгоритме.
      Если начинать не с правого верхнего, а n/2 в первой строке и также потом, при спуске.
      Пример, n=1000, m=2

  • @martintopchyan4399
    @martintopchyan4399 Рік тому +23

    we can do 2 binary searches,
    firstly we can go through the rows and find the right row(if the target is greater than the midRow's last element then startRow=midRow+1), and then do a binary search only for that row,
    in that case we will have O(logn + logm).

    • @DavidPotskhishvili-gp1km
      @DavidPotskhishvili-gp1km Рік тому +11

      This won't work. Try to find 8 using your algorithm in the example provided in the video.

    • @dmitryzhuk220
      @dmitryzhuk220 Рік тому +4

      Однако решить с такой сложностью всё таки можно если заметить, что для произвольного элемента m[i][j]

    • @mrseeker9075
      @mrseeker9075 Рік тому +1

      @@dmitryzhuk220 Не скажу что быстрее чем в видео нельзя решить, я как раз сейчас думаю над этим, но если элемент m[i][j] < k, то можно сказать лишь что наш элемент находится НЕ выше и левее, а иначе НЕ ниже и правее, то есть мы можем отрезать прямоугольную подматрицу в которой элемент не находится, но не выделить онную

    • @dmitryzhuk220
      @dmitryzhuk220 Рік тому +1

      @@mrseeker9075 о, действительно, спасибо за уточнение

    • @kiryl5476
      @kiryl5476 Рік тому

      ​@@mrseeker9075по идее матрицу можно нарезать на 4 меньшие матрицы (относительно ключевого элемента в центре) а потом рекурсивно повторять алгоритм до размера в 1 элемент и просто проверять этот 1 элемент на равенство. Единственное что есть риск переполнения стека на огромных матрицах

  • @f3ij0a
    @f3ij0a Рік тому

    Уточнение по условию задачи. Если двигаться по диагонали до первого большего всегда ли искомое будет в этом же столбце или в этой де строке?

  • @whitesteel2909
    @whitesteel2909 Рік тому

    проблема взялась из ниоткуда и мужественно решена ... браво

    • @SDesuu
      @SDesuu Рік тому +1

      Так суть программирования в том что всегда появляются "проблемы" которые нужно "мужественно" решать)

  • @lironblank6204
    @lironblank6204 Рік тому +17

    если постараться можно уменьшить до O(log(n)+log(m)) для этого надо заменить нахождение спомощю шагов на два бинарных поиска

    • @desmosmech7037
      @desmosmech7037 Рік тому

      Если постараться...
      Как ты поймешь что пора заканчивать делать бин. поиск по текущей оси и пора начинать делать бин. поиск по другой?

    • @smarthedgehog3185
      @smarthedgehog3185 Рік тому

      @@desmosmech7037 Признак конца поиска по строкам это два соседа
      один меньше
      другой больше
      бери меньший и ищи в этой строке

    • @roket132
      @roket132 Рік тому +1

      @@smarthedgehog3185 "бери меньший и ищи в этой строке" Если я правильно понял, то из примера на доске, вы найдете стоблец (11, 12, 16...) Но в нем нет 14)

    • @a_alex_l2041
      @a_alex_l2041 Рік тому

      Мне кажется человек не понял задачу.
      Но чтоб получить такую асимптотику надо сделать мёрдж, в один массив, но без пред обработки удачи.

    • @smarthedgehog3185
      @smarthedgehog3185 Рік тому

      @@roket132 Мы ищем сначало строку а потом в строке нужное поле.
      В строке между 10 и 18 есть 14. 14 какраза в строе с 10

  • @artemspiridovich2695
    @artemspiridovich2695 Рік тому +3

    но моя идея состояла в том чтобы идти исключительно по диагонали допустим слева направо... тобишь arr[0][0] далее arr[1][1] и так далее на перекрестии будет цифра либо отсекающая сектор точно меньше либо точно больше и потом нужно будет только вернуться от этой цифры вверх или вниз

    • @Meafel
      @Meafel 11 місяців тому

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

  • @chto_to_ne_tak.
    @chto_to_ne_tak. 9 місяців тому

    все круто , он видео почаще бы )

  • @danila_firstt
    @danila_firstt 6 місяців тому

    отличное объяснение, надо больше таких накидать Александр)

  • @alexnedelin7646
    @alexnedelin7646 Рік тому +3

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

    • @Gribozhuy
      @Gribozhuy Рік тому

      Найди по этому алгоритму число 7 или 11

    • @The14Some1
      @The14Some1 Рік тому

      не работает. Тебя может увести слишком далеко вправо, или слишком далеко вниз.

  • @RedBallOfLove
    @RedBallOfLove Рік тому +3

    Жаль только, что на собесах не обеспокоены качеством кода, а только задачками. Каждый раз, когда приходится обновлять сервисы гугла: firebase, admob, playgames - молишься, как бы хуже не стало. Ошибки без исправлений годами висят. Примерчик: подключаешь любой самый ссаный рекламный провайдер и ANR в норме, подключаешь admob и ANR в космос летит.

    • @The14Some1
      @The14Some1 Рік тому

      Странно, меня вот в одном из собеседований на трейни отшили именно по причине, что я не пользовался модулями и недостаточно явно поделил логику и вывод. А в другом отшили за то, что я это сделал, а они выбрали кандидатов, предпочёвших более простые решения.

  • @leomysky
    @leomysky Рік тому

    Спасибо за видео
    Всё очень доступно

  • @panfilovandrey
    @panfilovandrey Рік тому +1

    Красивое решение, класс!

  • @niqr7800
    @niqr7800 Рік тому +3

    Можно так же с левого нижнего угла начинать. Там работают теже правила, только в другом направлении

    • @kaxan1407
      @kaxan1407 Рік тому

      С левого верхнего угла тоже можно.

    • @niqr7800
      @niqr7800 Рік тому

      @@kaxan1407 Вообще-то нет)) У тебя с обоих сторон числа больше в таком случае. Ты просто не можешь определить, куда идти

    • @kaxan1407
      @kaxan1407 Рік тому

      @@niqr7800 да, я понел что в общем случае это не сработает минут через 5 после написания коммента

  • @TheAstralopitek
    @TheAstralopitek Рік тому +2

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

    • @oleksandr2234
      @oleksandr2234 Рік тому

      Во-первых - 2 раза быстрее не получится, тк мы теряем возможность двигаться по диагонали в одном направлении - тк если число, которое мы ищем, например, больше "серединного" - то оно может быть как правее, так и ниже.
      А во-вторых O(n/2+m/2) = O(n+m). Так что усложняя себе жизнь, вы не получаете никаких бонусов.

    • @TheAstralopitek
      @TheAstralopitek Рік тому

      @@oleksandr2234 да, я тоже об этом подумал, но в целом ожидаю что ускорение до 2 раз реально

  • @VasyaFF
    @VasyaFF Рік тому +2

    Жара! Нравится мне программирование.

  • @user-vf9if2zl4y
    @user-vf9if2zl4y Рік тому

    Класс, я бы никогда так не догадался сделать, хотя очень правильный шаг

  • @user-dh7lr6dm2f
    @user-dh7lr6dm2f Рік тому +5

    Друг, есть более быстрый способ. Первое, проверяем число в ячейке 1,1 и m,n убеждаемся что число К в середине и переборку начинаем с середины в таком случае получаем O((m+n)/2). Можно конечно и не проверять начало с концом тогда, тогда, если брать худший сценарий будет еще быстрее, однако если брать лучший сценарий то можно и без переборки сказать что нет числа в матрице

    • @Rofelka
      @Rofelka Рік тому

      Что есть середина матрицы 2х10? Мы должны курсор поставить в 1,5? А, может, в 2,6? Но мысль красивая с проверкой 1,1 и m,n. Если искомое число не в матрице (меньше наименьшего элемента или больше наибольшего), то выполним за 1 или 2 операции)

    • @user-dh7lr6dm2f
      @user-dh7lr6dm2f Рік тому

      @@Rofelka в предложенной Вами матрице 1,5 1,6 2,5 2,6 равнозначны

    • @SayXaNow
      @SayXaNow Рік тому

      @@user-dh7lr6dm2f Допустим дана матрица 100х200, надо найти число К=14. Вы начали с середины, там число 50. Все что вы теперь знаете, это то, что правую нижнюю часть можно отбросить. Но куда теперь вам дальше двигаться? Число К может быть в любой из трёх оставшихся областей. Причем оно может быть как левее середины, так и правее, как ниже середины, так и выше.

    • @user-dh7lr6dm2f
      @user-dh7lr6dm2f Рік тому

      @@SayXaNow точно, мой способ получается О(1.5 (m+n))

    • @leofender5753
      @leofender5753 Рік тому

      @@SayXaNow а если дальше опять повторить ход в середину оставшейся области? то есть по сути всегда делим на 2 и сверяем....и того вместо 7 будет 5 ходов

  • @bel8504
    @bel8504 Рік тому +5

    Круто. А главное красиво.Лично мне первое пришедшее в голову решение было:
    1) берем среднее по номеру число в средней строке. Если такого нет - ближайшее (к примеру 7 если всего 15. Или 8. Без разницы). Мысленно мы разделили по строке и столбцу на 4 секции. Если К меньше числа, то мы отсекаем все большие числа по строке и столбцу. И повторяем это всё.
    В программировании я совершенно не разбираюсь, думала с точки зрения математики скорее.

    • @hod-pj
      @hod-pj Рік тому

      была детская задачка отгадать число от 1 до 1024 за 10 попыток. тебе говорят больше или меньше задуманного то что ты назвал. лень проверять, но думаю такой способ более эффективен чем предложенный.

    • @QuarkWasp
      @QuarkWasp Рік тому +1

      Да, этот способ является самым эффективным и называется двоичным поиском.

    • @OstapP
      @OstapP Рік тому

      ​@@QuarkWasp, двоичный поиск работает с линейными массивами. Такую матрицу к линейному массиву свести очень дорого.

  • @user-zw2wr2tm3o
    @user-zw2wr2tm3o Рік тому

    А что если по главной диагонали спуститься до числа превосходящего заданное. И потом проверить числа слева и сверху?

  • @SkyHaven-si4lv
    @SkyHaven-si4lv 8 місяців тому

    ЛЕГЕНДА

  • @Proezdom-zx2tl
    @Proezdom-zx2tl Рік тому +11

    В принципе всё правильно. Но исходя из того-же бинарного принципа начинать надо не с краёв а с середины. То есть с числа 16. Ну и идти придётся не в одну сторону, а в зависимости от сравнения.
    В данном конкретном случае дойдём до 14 за 2 хода 🙂

    • @Mustitz
      @Mustitz Рік тому +2

      Ну да, первое желание всё-таки получить $O(\ln n + \ln m)$, а не $O(n+m)$...

    • @SayXaNow
      @SayXaNow Рік тому +2

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

    • @dmitry7464
      @dmitry7464 Рік тому

      @@SayXaNowтоже подумал о бинарном поиске

    • @Proezdom-zx2tl
      @Proezdom-zx2tl Рік тому

      @@SayXaNow
      Я вот как думаю:
      - В принципе даже условие задачи не совсем строгое - что такое самый быстрый (или оптимальный) алгоритм поиска?
      - В общем случае я вижу как минимум 2 интерпретации.
      - 1 - Минимальное количество шагов в среднем.
      - 2 - Минимизировать количество шагов для самого плохого случая.
      Очевидно, что алгиритмы получатся разные.
      Для второго алгоритма, особенно для большого количества рядов (например 1 000 000 000) не оптимально двигаться последовательно по лесенке.
      Надо целый массив разбивать на кучки (на 2, а лучше на 3), проверять граничные условия прыгая из одной в другую и убирать целые кучки (суб массивы).
      Когда осталась кучка небольшого размера (надо считать какого), тогда уже можно идти по лесенке от верхнего правого угла...
      Ну может я и не прав???

    • @SayXaNow
      @SayXaNow Рік тому +3

      @@Proezdom-zx2tl Ну задача с подвохом. я всегда топил и топлю за бинарный алгоритм. В матрице случайных упорядоченных значений размером 2500х10000 он показывает скорость нахождения любого элемента в среднем за 67 шагов. Казалось бы - фантастика, ну что за лохи вообще топят за этот линейный аутизм, ведь налицо логарифмическая скорость.
      Но надо учесть один нюанс. могут попадаться квадратные блоки данных, в которых числа расположены особым образом и полностью удовлетворяют условию задачи (правее всегда числа больше, снизу от любого числа тоже всегда больше), но для которых не существует в принципе алгоритма быстрее, чем линейный ступеньками.
      И если вдруг в моей матрице мне попался именно такой блок размером 2500х2500 то максимально неудачный расклад для бинарного поиска составит 50000 шагов и примерно 15000 в среднем для любого числа такого блока. Не трудно посчитать что неторопливый линейный тут покажет лучший результат. И т.к. никаким способом нельзя быстро проверить попался нам такой блок или нет, я бы не рискнул использовать быструю бинарку для слишком больших квадратных матриц. Сначала бы убедился что большая сторона M превосходит меньшую N хотя бы в 5 раз. А если ярко выраженная прямоугольная длинная типа 1000х17000 - тут даже обсуждать нечего - только бинарный поиск.
      Страшилка конечно это все, да и вероятность мала нарваться на такое, поэтому юзаю бинарки и не заморачиваюсь. Но как минимум надо помнить теперь об этом. Такие вот любопытные подробности всплыли, когда занимался тестами.

  • @core2mind
    @core2mind Рік тому +5

    Кажется, что ходить до границы матрицы из верхнего правого угла может быть расточительно. При какой-нибудь матрице 1e12 x 1e12 (абстрактная большая цифра). Может стоить добавить в код условие про то, что если k < верхнего левого угла || k > нижнего правого угла, то искать нет смысла (false).

    • @VasillaRobocraft
      @VasillaRobocraft Рік тому

      Ну как раз на этом этапе можно использовать бинарный поиск

    • @dmytrozazulin1858
      @dmytrozazulin1858 Рік тому

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

    • @core2mind
      @core2mind Рік тому

      @@dmytrozazulin1858 , по-моему вы либо не так интерпретируете мое сообщение, или не так интерпретируете условие.
      Простой вопрос:
      Если в правом нижнем углу матрицы значение, равное 500, может ли в матрице быть значение, например, 501?
      Если да, составьте пример такой матрицы, я посмотрю, как вы это сделаете, не нарушая условий

    • @dmytrozazulin1858
      @dmytrozazulin1858 Рік тому

      @@core2mind Ясно, я думал вы хотите внести коррективы в сам процесс поиска. А это просто проверка вырожденного случая.

    • @core2mind
      @core2mind Рік тому +1

      @@dmytrozazulin1858 , ну это по сути внесение изменений в алгоритм поиска, но не в алгоритм скана матрицы самой. Если у нас матрица триллион x триллион, есть ли смысл долго по ней ходить, если за константное время можно сразу сделать вывод, что ходить по ней нет смысла. Я это хотел донести, если что.
      В алгоритме, представленном в видео, уже есть предварительные проверки перед сканированием матрицы, мой поинт был лишь в том, что возможно стоит расширить эти проверки.

  • @user-tq1et2ik3z
    @user-tq1et2ik3z Рік тому

    Александр, спасибо! Но я не совсем понял, как выбирать «угол», с которого начинать поиск?

  • @gameflame4633
    @gameflame4633 Рік тому +10

    То, что сразу полезло в голову:
    1) Проходимся по каждому элементу первой строки и ищём первое число, которое будет больше k
    2) Делаем то же, но для первого столбца
    3) Ограничиваем область поиска k найденными ранее элементами массива
    4) Используем любой поиск.
    В худшем случае ограничение у нас займёт O(n+m), а поиск - O(n1 * m1), где n1 и m1 - элементы-ограничители (при прохождении по каждому элементу).

    • @user-qz3vf1yv7p
      @user-qz3vf1yv7p Рік тому

      Ух-ты, тоже это в голову пришло

    • @realvaniog
      @realvaniog Рік тому

      Можно еще ограничивать область если найти число которое меньше k (не рассматривать левую верхнюю область). И тогда такое решение может быть даже быстрее чем то которое рассказали.

    • @OstapP
      @OstapP Рік тому

      ​@@realvaniog, объясните пошагово. Звучит как бред.

    • @OstapP
      @OstapP Рік тому

      В худшем случае (k>18), а это почти половина возможных k, размер матрицы не уменьшается. Но ваше решение натолкнуло меня на другое. Нужно, чтобы опытный алгоритмист проверил, может я тоже не прав.
      Решение:
      1) в первой строке доходим до последнего =к. Зачеркиваем для себя все, что ниже.
      3) в уже ограниченой матрице идем по первому столбцу до последнего =к. Зачеркиваем для себя, все что левее.
      Проходки логично делать бинарным поиском. Если я все правильно понимаю по крайней мере в этой таблице за эти 4 этапа находим наше число. Если таблица больше надо пример, чтобы понять что дальше делать, но так мы гарантированно сильно уменьшаем зону поиска.
      Получается 2log(m) + 2log(n)

    • @realvaniog
      @realvaniog Рік тому

      @@OstapP Если нашли число меньшее k, то нам не подходят все числа которые (одновременно) левее и выше этого найденного числа (там все числа меньше k). Аналогично с числом большим k. Т.о любое число неравное k ограничивает нашу область поиска.

  • @user-wg4pl4pf5n
    @user-wg4pl4pf5n Рік тому +3

    Изменено: не работает(
    Мне кажется есть не менее эффективный способ, хотя хз насколько он будет лучше в коде.
    1) делим количество строк на 2 (округляя) и начинаем с этой цифры. (В данном случае 3)
    2) если число меньше то идем вверх, больше вниз. (В данном случае вниз, доходя до 10)
    3) теперь также делим уже столбцы (и округляем, в данном случае это не нужно, но при изменении условий пригодилось бы), то есть мы на числе 14.
    4) Если число меньше то идем в лево, если больше в право. Но в данной ситуации это не пригодилось.
    В чем же преимущество этого метода?
    Если считать именно колличество ходов их будет максимум 7. (Если ищем число 36)
    В случае описанном в видео 10. (Если ищем число 18)

    • @desmosmech7037
      @desmosmech7037 Рік тому

      Найди число 11 по даному алгоритму

    • @smarthedgehog3185
      @smarthedgehog3185 Рік тому

      @@desmosmech7037 Это просто крайний случай для бинарного поиска по строкам. Ничего не меняет.
      Бинарный поиск это метод сходящихся интервалов. Ты просто ускоряешь их сходимость деля на два длину.
      В Численных методах этот метод ещё называли поиском льва в пустыне :)
      Грубо говоря там можно и площади делить отрезком.
      Т.е. сначала делить матрицу по столбцам потом по строкам в зависимости от того какая часть длиннее.

    • @user-wg4pl4pf5n
      @user-wg4pl4pf5n Рік тому

      @@desmosmech7037 верно, спасибо что сказал.

  • @Qwerty-fn3rf
    @Qwerty-fn3rf Рік тому

    Оч классно , спасибо 🔥

  • @pollux_youtubehd1558
    @pollux_youtubehd1558 Рік тому

    Саша у меня Математика 00 как я могу научиться Алгоритмам с нуля до про и как где откуда надо начат ?

  • @_Kio_
    @_Kio_ Рік тому +4

    Самое быстрое решение, которое я смог найти, вот такое:
    Находим центральную строку, бинарным поиском делим её на две части - до и после искомого числа.
    Проводим от этой точки мысленную горизонтальную и вертикальную линию, тем самым разделив таблицу на 4 части.
    Левый верхний угол выкидываем, там все числа меньше искомого. Правый нижний тоже выкидываем, там все числа больше. А в левом нижнем и в правом верхнем углах запускаем этот алгоритм рекурсивно. Получаем логарифмическое время посика. P.S. видос ещё не смотрел.

    • @astashch
      @astashch Рік тому

      мне тоже кажется делить на квадраты интересная идея, первое что пришло на ум, до просмотра решения)

    • @diplodogs
      @diplodogs Рік тому

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

    • @yuvis_cr
      @yuvis_cr Рік тому

      квадраты получаются только не квадратные в данной матрице

    • @allex-all
      @allex-all Рік тому

      Как я и думал, можно за log(m+n)

    • @lotgon911
      @lotgon911 Рік тому

      Ты можешь исключить только один квадрат за шаг

  • @SentoxV
    @SentoxV Рік тому +3

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

  • @VasillaRobocraft
    @VasillaRobocraft Рік тому

    Классная задача, спасибо

  • @allex-all
    @allex-all Рік тому +2

    Есть подозрение что можно ещё улучшить алгоритм до log(m+n) ?

    • @dmitryzhuk220
      @dmitryzhuk220 Рік тому

      Да, есть. Подсказка: возьмите произвольный элемент матрицы, сравните с k и скажите где после этого может быть искомый элемент. Ну а дальше √2 и ничего сверх сложного

  • @lalkaveka4417
    @lalkaveka4417 Рік тому +4

    Первая (и последняя идея)
    1)Проверить первый столбец и первую строку на наличие цифр больше 14 и отсечь их. В нашем случае матрица станет 4 на 4.
    2) проверить в обратном порядке последний столбец и строку новой матрицы (4 на 4) и отсечь все, что меньше 14. (Осталось 2 на 2)
    3) оставшуюся маленькую матрицу просто перебрать
    А потом я досмотрел видео и в очередной раз понял, что я тупой

  • @Andre-sb2ci
    @Andre-sb2ci Рік тому

    вопрос: а что это за код такой, в котором записывается решение?

  • @Magomed-r
    @Magomed-r 2 місяці тому

    Было интересно

  • @MrAlexVelik
    @MrAlexVelik Рік тому +1

    Сделал эту задачу в JavaScript таким образом до того, как посмотрел решение Саши. Как думаете, тут есть O(n+m)? Мне кажется, что это тоже самое, только без цикла while. Всегда ли вложенный массив приведёт в итоге к O(m*n)? Потому что в моём решении нет итераций вообще по всем элементам массива.
    const findK = (arr, k) => {
    let row = 0;
    let column = arr[row].length - 1;
    for (row; row < arr.length; row++) {
    for (column; column >= 0; column--) {
    if (arr[row][column] === k) {
    return true;
    }
    if (k > arr[row][column]) {
    break;
    }
    }
    }
    return false;
    };

    • @user-tw7lm5nw1g
      @user-tw7lm5nw1g Рік тому +2

      Сделал без while, но с двумя for. Предложенное в видео решение выглядит читабельнее. Сложность обоих решений одинаковая - O(m + n)

  • @nathanblake1535
    @nathanblake1535 Рік тому

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

  • @vtemv
    @vtemv Рік тому

    Ловко ты мне в рекомендациях попался, не зря в гугле работаешь)

  • @sergeymatpoc
    @sergeymatpoc Рік тому +1

    да, так же подумал как в решении, только сравнивать не "то что меньше", а "то что больше" (возможно менее эффективное решение). Т.е. если K больше чем a(n-1,m) то двигаться вниз. И еще я бы ввел проверку на "крайние" условия типа к !=0 и a(n,m) >=k

  • @ilyat2925
    @ilyat2925 Рік тому +2

    Хороший результат, линейный алгоритм оптимизированный для двумерного случая. Для еще более быстрого поиска можно бинарный поиском найти строку и далее найти столбец также бинарным поиском. Сложность будет еще меньше.

    • @OstapP
      @OstapP Рік тому +1

      Ваш алгоритм даст быстрый неправильный овет для 11, 12, 15, 16, ....

    • @ilyat2925
      @ilyat2925 Рік тому

      @@OstapP я написал не то что подумал, бинарным поиском искать и столбец и строку. Ответ будет правильным так как и там и там отсортированные множества

    • @OstapP
      @OstapP Рік тому +1

      @@ilyat2925 , можно этапно? Я не понял ваш алгоритм.

  • @artempogorelov1934
    @artempogorelov1934 Місяць тому

    Чем бинарный поиск числа с минимальной разницей от искомого по строке и столбцу хуже? Таким образом находится следующая строка и столбец.
    O(log n + log m), разве нет?

  • @Zeffir123
    @Zeffir123 Рік тому

    а с левого нижнего угла не быстрее получится?

  • @thayornwarrior2785
    @thayornwarrior2785 3 місяці тому

    хочу быть таким же умным парнем как ты✊

  • @chalex2k
    @chalex2k Рік тому

    Вау! Красивое решение!
    Сразу придумал бинпоиск. И еще бинпоиском по первому и последнему столбцу можно убрать часть строк, в которых точно нет искомого числа. Но это асимптотику не улучшит.

  • @tatsutakamaro
    @tatsutakamaro Рік тому

    За 15 мин надо готовый рабочий код написать или только логику решения предоставить?

  • @Kozlov_Production
    @Kozlov_Production 8 місяців тому

    А почему не пойти из левого верхнего угла по столбцам вниз? Как дойдём до 18, вернуться назад к 10ти и пойти вправо до 14ти.

  • @user-cu5je9eq2h
    @user-cu5je9eq2h Рік тому

    Почему нельзя проверить сразу число по средине. Если К больше того, что по середине, идти нужно к правому, если оно меньше правого, то прочёсываем числа вверх по матрице?

  • @DarthYodaDarth
    @DarthYodaDarth Рік тому

    А почему отправной точкой является верхнее правое число? Почему другие углы не подойдут?

  • @vladimireliseev7602
    @vladimireliseev7602 11 місяців тому

    Вопрос, а почему time complexity O(n+m) ?

  • @tushkaxx4552
    @tushkaxx4552 Рік тому +1

    Добрый вечер. В чём принципиальная разница между обходом массива с конца и с начала?

    • @loomikey230
      @loomikey230 Рік тому

      Ни в чем, здесь главное- принцип найти. Представь что в конце квадрильон на мультимильон- идти к началу будешь дольше в поисках 1. Задача симметричная и решение тоже) и я бы проверил сначала, откуда начинать поиск- в известной матрице больших размеров можно искать методом наименьших квадратов 😊

    • @oleksandr2234
      @oleksandr2234 Рік тому

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

  • @1654045
    @1654045 Рік тому

    Просто огонь!

  • @Alexey0795
    @Alexey0795 Рік тому

    что будет если начать из другого угла?

  • @hesoyammm
    @hesoyammm Рік тому

    смысл давать задачи на собеседовании в режиме онлайн, если их все равно готовят заране?е

  • @ntbatyr
    @ntbatyr Рік тому

    Мне кинули задачку.
    Дан csv файл со списком категорий и подкатегорий
    _______________
    id,name,parent
    ------------------------
    данные в файле в разброс, вложенность неограниченна. Нужно построить дерево без рекурсии. Как это возможно сделать?

  • @dmitryrakov2795
    @dmitryrakov2795 Рік тому

    Привет! А почему так мало видосов на канале?

  • @sibirychok
    @sibirychok Рік тому

    Ну в принципе можно и с единицы начать, всё получается, главное придумать свои правила вычисления!

  • @user-xr4oe8qs2o
    @user-xr4oe8qs2o Рік тому +1

    а что мешает и в этом решении начать не с верхнего правого угла, а с середины матрицы?

    • @oleksandr2234
      @oleksandr2234 Рік тому

      С верзнего-правого или нижнего-левого получаем простую формулу: если нужное число менье текущего - идем всегда влево, если больше - всегда вниз..
      С середины мы такую формулу не получим, тк у нас нет однозначного ответа - идти от числа 16 вверх, или налево (или от числа 9 - вниз или вправо).

  • @fullfree1812
    @fullfree1812 Рік тому

    Респект!

  • @ES-ng3el
    @ES-ng3el Рік тому

    Красавчик. Подскажите, а вы менторством занимаетесь ?

  • @47clere
    @47clere Рік тому

    Сразу подумал что нужно идти по диагонали.
    Вот только не объяснил почему с правого верхнего угла пошли. Без разницы с какого угла идти, числом может быть как ближе к наименьшему так и ближе к на большему, соответственно если искомое число например 2 то поиск будет максимально долгим.
    Решение этой задачи можно немного оптимизировать так: mid = (max + min) / 2
    Если n < mid то идём по диагонали с верхнего левого угла, если n > mid то с правого верхнего угла. Дальше действуем без изменений.

  • @user-py4yc8ny3b
    @user-py4yc8ny3b Рік тому

    Коды читать и писать не умею, но решение 1 в 1. Вот только пришлось подержать паузу подольше. Есть вопрос к условию задачи...
    Получается нам важно только наличие числа (true/false)? Амазон дополнительно не интересовались сколько чисел "K" в матрице (ведь их в диагональ может быть очень много)?

  • @mactepmactepctba3853
    @mactepmactepctba3853 Рік тому

    Я конечно не эксперт, но я сразу нашел число 14. Было трудно, просто включил монитор на котором смотрел это увлекательное видео.

  • @mzmzmzmzmq
    @mzmzmzmzmq Рік тому +1

    а если попробовать бинарным поиском сначал искать строку, в которой 0-вой элемент ближе всех к К, но меньше K, а потом уже бинарный поиск по этой строке? тогда получится log(n) + log(m), что меньше, чем n+m

    • @sangoforto3589
      @sangoforto3589 Рік тому

      Я тоже именно так и подумал

    • @SayXaNow
      @SayXaNow Рік тому

      Вы на верном пути, дам подсказку: log(n) + log(m) у вас не выйдет, т.к. вы не сможете гарантированно за два бинарных поиска найти число, но вот log(n)*log(m) - один из лучших вариантов. Про окончательный ответ из видео забудьте. Последовательный поиск вместо бинарного в упорядоченной последовательности - это провал собеседования. Хуже только перебор всех значений, зато в одну строчку.

    • @mzmzmzmzmq
      @mzmzmzmzmq Рік тому

      @@SayXaNow почему за суму логов не выйдет?

    • @mzmzmzmzmq
      @mzmzmzmzmq Рік тому

      @@SayXaNow можно ведь найти число не точно искомое, но рядом с ним стоящее за лог

    • @SayXaNow
      @SayXaNow Рік тому

      @@mzmzmzmzmq за первый лог N для строки вы нашли максимально близкое к К и знаете теперь ограничение конца строки - допустим это индекс I. За второй лог по М вы нашли в столбце I максимально близкое к К число и знаете теперь ограничение длинны столбца, допустим это индекс J.
      Вы использовали два лога, но у вас еще осталась непроверенная область [0, 0, J, I] дл которой нужно повторить операцию. Так понятнее? За сумму логов вы лишь сократите область поиска, но гарантированно К не найдете.

  • @karbofos80
    @karbofos80 Рік тому

    начинать перебирать массив с левого верхнего или с правого, вопрос не принципиальный т.к число К может быть любым

    • @RashadFaridov
      @RashadFaridov Рік тому

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

  • @gNikro
    @gNikro Рік тому

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

  • @artemspiridovich2695
    @artemspiridovich2695 Рік тому +1

    а вообще можно совместить и сделать тройное решение тобишь находить быстро точку входа допустим цифру 17 потом от нее идти влево вниз и одновременно вверх вправо

  • @IstMirWurst
    @IstMirWurst Рік тому

    на каком языке нужно искать ответ?

  • @user-wy4fz7ey4y
    @user-wy4fz7ey4y Рік тому

    а почему искать нужно начинать с угла? почему не с "условного" центра матрицы?

  • @revibesoft
    @revibesoft 7 місяців тому

    а какие языки программирования надо знать чтоб попасть в известные IT компании (google,amazon и.тд)?

  • @volk5762
    @volk5762 Рік тому

    Ахуенное решение, спасибо за видос, ты ГЕНИЙ!

  • @alexeymironenkov
    @alexeymironenkov Рік тому

    Саша, не понял, зачем начинать именно с правого верхнего угла. Почему не с левого?
    Я б начинал сверху откуда-нить из
    m*(14-a_11)/(a_m1-a_11), где m - число столбцов

  • @zaga_mx6865
    @zaga_mx6865 Рік тому

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

    • @user-of8lf7yj8o
      @user-of8lf7yj8o Рік тому

      Учить информатику начиная со школьной

  • @vladisfaer
    @vladisfaer Рік тому

    А что если перебирать не всю матрицу? Можно исключить некоторые столбцы и строки

    • @user-mr1tl6tt7g
      @user-mr1tl6tt7g Рік тому

      Как ты это программе объяснишь?

  • @by_Fredijkeeeeeee
    @by_Fredijkeeeeeee Рік тому

    Как увидел, сразу начал по диагонали, но не с того угла. Немного недодумал)) Тем не менее, внутренний "я" доволен собой xD

  • @user-fl2mc9lx1p
    @user-fl2mc9lx1p Рік тому

    Решил так же! Почти ) Понял, что надо идти лесенкой. Сперва в 1-й строке найти число большее к, сдвинуться к предыдущему индексу в строке, увеличить индекс по вертикали. Все, как вы описали. Единственное отличие - я пошел слева направо. Вам хорошо, вы видите все значения в массиве, а программа их не видит. Первое же левое число в строке может быть к! Или другое, достаточно "левое" число. Нет никаких преимуществ у больших чисел справа перед меньшими числами слева - к может стоять ближе как к левому, так и к правому краю.
    Неплохо было бы еще двоичный поиск min числа > к в 1-й строке добавить! Потому, как можно почти всю строку пропахать в поисках такого числа, а оно окажется ближе к краю, противоположной началу поиска.
    Спасибо за задачу! Понравилась.

    • @Anton_K15
      @Anton_K15 Рік тому

      Я так же подумал, но понял что делается одно лишнее движение каретки с лева на право. А потом в итоге каретка движется с права на лево и в низ.

  • @svetsguitarplaying3681
    @svetsguitarplaying3681 Рік тому

    Бинарный поиск?