Найти в Дзене
Бывалый Айтишник

Leetcode, задача 392. Is Subsequence: По следам воспоминаний 🕵️‍♂️

Оглавление

Привет, исследователь кода! 🖖 Сегодня мы с вами окунёмся в глубины наших воспоминаний. В жизни каждого из нас есть моменты, которые мы хотели бы вспомнить. Иногда мы помним фрагменты истории, но не уверены, действительно ли они являются частью нашего прошлого. Это как пытаться понять, является ли одна строка подпоследовательностью другой. Именно это мы и будем делать сегодня!

Задача дня: у нас есть две строки, s и t. Нам нужно определить, является ли строка s подпоследовательностью t. Подпоследовательность — это то, что получается при удалении некоторых символов из строки без изменения порядка оставшихся символов. Как, например, "ace" — это подпоследовательность "abcde", но "aec" — уже нет.

Но зачем это нам? Представьте, что t — это история вашей жизни, а s — воспоминания, которые вы хотите проверить. Мы пытаемся понять, действительно ли эти воспоминания были частью вашего прошлого. 🤔

Что вас ждёт в этом посту:

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

Если вы готовы отправиться в это путешествие по памяти и коду, держитесь крепче! 🚀

🔗 Оригинальное условие задачи на Leetcode

Шаг 1: Простое и прямолинейное решение 👀

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

Идея:

  1. Создать два указателя, один для каждой строки.
  2. Перемещать указатели по строкам, сравнивая символы.
  3. Если символы совпадают, переместить указатель для строки s на следующий символ.
  4. Если мы достигли конца строки s, то она является подпоследовательностью t.
-2
def isSubsequence(s, t):
if not s:
return True

s_pointer, t_pointer = 0, 0

while t_pointer < len(t):
# Если символы совпадают, двигаем указатель для s
if s[s_pointer] == t[t_pointer]:
s_pointer += 1
# Если достигли конца s, то успех!
if s_pointer == len(s):
return True
t_pointer += 1

return False

Шаг 2: Учет множественных входов для s 🌪️

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

Идея:

  1. Создать список списков для каждого символа в t, где каждый внутренний список содержит индексы этого символа в t.
  2. Для каждого символа в s использовать бинарный поиск, чтобы найти следующий наименьший индекс в соответствующем списке индексов.

Этот подход будет более быстрым для множественных запросов, но его реализация немного сложнее. В этом посту мы оставим этот подход как упражнение для читателя. 😉

Финальный код в стиле LeetCode 🎬

-3
class Solution:
def isSubsequence(self, s: str, t: str) -> bool:
if not s:
return True

s_pointer, t_pointer = 0, 0

while t_pointer < len(t):
if s[s_pointer] == t[t_pointer]:
s_pointer += 1
if s_pointer == len(s):
return True
t_pointer += 1

return False

Комментарий: Надеюсь, что ваша память не такая запутанная, как некоторые из этих строк. Но даже если это так, Python всегда на вашей стороне! 🐍

Столкновение реальности: может ли это работать в реальной жизни? 🌍

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

Применение в реальной жизни

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

Производительность

Мы установили, что наша текущая реализация работает достаточно быстро для большинства случаев. Однако, что если у вас есть гигантский текст (например, полный текст "Войны и мира") и множество разных подпоследовательностей для проверки? В таком случае, предварительная индексация текста может быть выгодной. Это позволит быстрее проверять, является ли данная строка подпоследовательностью, не проходя каждый раз по всему тексту.

Заключение

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

Анекдот на закуску:

- Ты помнишь, как в прошлом году на нашей встрече выпускников я выиграл в лотерею миллион?
- Нет, такого не было. Это, наверное, твои ложные воспоминания.
- Ну да, но было бы круто, правда?

Пока и удачного кодинга! 🚀

Наука
7 млн интересуются