Рубрики
Без рубрики

Стоимость доски в Python: Можете ли вы решить эту простую проблему строки?

<< Неделя 4: двоичный поиск | Просмотреть решение на GitHub | Неделя 6: Разное 3 >> (Источник изображения: … Tagged с Python, Codenewbie, Compurly Science.

<< Неделя 4: двоичный поиск | Вид Решение на GitHub | Неделя 6: Разное 3 >>

(Источник изображения: BuzzFeed) Несмотря на все, я все еще просто червь на строке.

Счастливого понедельника, и добро пожаловать на доску на доске в Python. Я надеюсь, что на прошлой неделе я не пугаю вас с алгоритмами и математикой, поэтому на этой неделе мы рассмотрим более легкую проблему с участием строк. Давайте прыгнем прямо в.

# Determine if a string has all unique characters. 
# You cannot use additional data structures. 

Довольно просто, верно? Это потому, что это первый вопрос, перечисленный в разделе «Массивы и струны» Взломать интервью по кодированию . Есть много разных подходов, которые мы можем выбрать, которые отличаются во времени и пространстве, поэтому мы пройдем через пару из них.

Первый подход: грубая сила

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

«Брутная сила» точно так же, как кажется. Представьте, что у вас была головоломка, где все части были одинаковыми. Вам придется слепо попробовать каждую комбинацию, пока не найдете два, которые соединяются друг с другом. Здесь мы собираемся проверить каждого персонажа для каждого другого персонажа в строке, чтобы увидеть, совпадает ли это. Давайте начнем с определения метода (либо в Repl.it, либо вы можете попробовать свои силы в старомодном карандаше и бумаге). Он займет одну строку в качестве параметра, которую мы будем называть с .

def is_unique(s):
    pass

Далее мы определим первый для петля. Будут вложенные петли, и этот будет проходить через каждого символа в строке до второго по последнее. Почему до последнего персонажа? Мы будем сравнивать каждого персонажа с теми, кто следит за ним, и их нет после последнего персонажа в списке.

def is_unique(s):
  for i in range(len(s) - 1):

Теперь давайте сделаем для петля внутри этого. Это начнется со следующего места в списке, которое мы будем называть индекс j . Индекс J Переверните список до конца, сравнивая его с персонажем в первом индексе, я Анкет Мы вернем False, если они соответствуют, то есть символы в строке не являются уникальными.

def is_unique(s):
  for i in range(len(s) - 1):
    for j in range(i + 1, len(s)):
      if s[j] == s[i]:
        return False

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

def is_unique(s):
  for i in range(len(s) - 1):
    for j in range(i + 1, len(s)):
      if s[j] == s[i]:
        return False
  return True

Вот и все! Призыв is_unique ("Привет") должен вернуть ложь, и is_unique ("пока") должен вернуть правду.

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

С одной стороны, наше решение заполняет требование «нет дополнительных структур данных. «Мы просто пробираемся через строку без сохранения информации в новой структуре данных. Это дает нам пространственную сложность O (1), не имея отношения к длине струны.

Как насчет сложности времени? Чтобы представить худший случай, нет уникальных персонажей, поэтому все вложенное петля должна работать. Это мы можем предположить, чтобы быть о O (n 2 ), хотя мы сохранили некоторое время, проверив каждую пару только один раз. Я сделал математику, и это технически O (∑ n-1 i = 1 i), но это не типичная временная сложность, поэтому мы скажем, что это O (n 2 ). Если вы помните График с прошлой недели , O (n 2 ) довольно ужасно. Тем не менее, речь идет о лучшем, что мы можем сделать, если мы не можем сделать никаких новых дополнительных структур данных или изменить исходную строку.

Более оптимально: сортировать строку

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

Питон .sort () Метод работает только в списках. Итак, наша первая задача будет заключаться в том, чтобы превратить строку в список символов. Я повторяю, но для проблем с доской в Python это действительно то, что вы захотите знать наизусть.

s_as_list = [char for char in s]

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

Как только мы переведем строку в список, мы можем позвонить sort () в теме.

def is_unique2(s):
  s_as_list = [char for char in s]
  s_as_list.sort()

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

    prev = ""
    for letter in s_as_list:

Для каждой итерации мы хотим сделать одну из двух вещей:

  1. Если символ такой же, как и предыдущий, верните False.
  2. В противном случае, сделайте этот персонаж новым предыдущим персонажем.

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

  prev = ""
  for letter in s_as_list:
    if letter == prev:
      return False
    else: 
      prev = letter

Наконец, если для Loop был успешно выполнен, не найдя матча, мы вернем True за пределами петли. Вообще:

def is_unique2(s):
  s_as_list = [char for char in s]
  s_as_list.sort()
  prev = ""
  for letter in s_as_list:
    if letter == prev:
      return False
    else: 
      prev = letter
  return True

Сложность времени для метода с использованием сортировки

Сложность нашего метода зависит от сложности времени Python’s .sort () метод Python использует Timsort, который является гибрид между слиянием и вставкой , если вы знакомы с ними. Средняя и худшая сложность случая – O (n log n). Кроме того, мы пробираемся через список n раз, хотя мы пренебрегаем этим, так как O (n log n) больше. Однако, поскольку мы должны составить новый список для сортировки строки, мы больше не заполняем требование, чтобы дополнительные структуры данных не могли быть использованы.

Еще более оптимальная сложность времени: используйте словарь

Давайте полностью выбросим правило «Нет дополнительных структур данных». Какое решение мы могли бы придумать? В Взломать интервью по кодированию , первое решение предполагает использование массива длины 128, дробь алфавита Unicode. Однако, если вы использовали Python один или два раза, теперь вы, вероятно, знаете, чтобы использовать словарь.

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

from collections import defaultdict

def is_unique3(s):
  dd = defaultdict(bool)

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

  for char in s:
    if dd[char]:
      return False
    dd[char] = True

Наконец, мы вернемся за пределами цикла, если каждый персонаж появится только один раз. Вообще:

def is_unique3(s):
dd = defaultdict(bool)
for char in s:
if dd[char]:
return False
dd[char] = True
return True

Временная сложность для метода словаря

Какова у нас сложности времени? Мы пробираемся через список n раз, и требуется O (1), чтобы получить доступ к каждому элементу в словаре, поэтому наша сложность O (n), даже лучше, чем наш предыдущий подход. Тем не менее, теперь у нас есть словарь в нашем хранилище, которого было раньше. Вы обнаружите, что время и пространство – это компромиссы, когда дело доходит до информатики, и принятие наилучшего решения зависит от ситуации.

Это все на сегодня, увидимся на следующей неделе! Если у вас есть вопросы или какие -либо идеи для того, какую проблему решать дальше, не стесняйтесь оставить комментарий.

<< Неделя 4: двоичный поиск | Вид Решение на GitHub | Неделя 6: Разное 3 >>

Шеймус Хейккила ранее был ассистентом преподавателя в Генеральной Ассамблеи Сиэтл. Этот блог не связан с GA.

Оригинал: “https://dev.to/pythonwb/whiteboarding-in-python-can-you-solve-this-simple-string-problem-514o”