Лайфкодинг Python
⌨️ Задачи
Задача №1
# Что выведет этот код?
class father:
def init(self, param):
self.a = param
class child(father):
def init(self, param)
self.b = param
obj = child(22)
print ("%d %d" % (obj.a,obj.b)
Проблема в коде связана с тем, что вы забыли правильно определить метод __init__ (пропущены двоеточия после def init(self, param)). Кроме того, вы не вызываете метод __init__ родительского класса father. Вот исправленный вариант:
class father:
def __init__(self, param):
self.a = param
class child(father):
def __init__(self, param):
super().__init__(param)
self.b = param
obj = child(22)
print("%d %d" % (obj.a, obj.b))
Этот код выведет:
22 22
Он создает объект класса child с атрибутами a и b, оба устанавливаются в 22, и затем выводит значения обоих атрибутов.
Задача №2
# Найти написать функцию, которая отвечает на вопрос
# можно ли путем замены, удаления или добавления одного символа
# получить из певой строки вторую
("abc" , "avc") -> true
('ab', 'abcd') -> false
("avcc", "acc") -> true
Решение:
def can_transform(str1, str2):
len_diff = abs(len(str1) - len(str2))
# Если длины различаются более чем на 1 символ, невозможно преобразовать
if len_diff > 1:
return False
# Если длины одинаковые, проверяем на замену символов
if len_diff == 0:
diff_count = 0
for char1, char2 in zip(str1, str2):
if char1 != char2:
diff_count += 1
return diff_count == 1
# Если длины отличаются на 1, проверяем на удаление или добавление одного символа
if len_diff == 1:
# Проверяем, является ли одна из строк подстрокой другой с добавленным или удаленным символом
short_str = min(str1, str2, key=len)
long_str = max(str1, str2, key=len)
for i in range(len(short_str)):
if short_str[i] != long_str[i]:
return short_str[i:] == long_str[i + 1:] # Проверяем удаление или добавление
return True # В случае, если короткая строка - префикс длинной строки
return False
# Примеры использования
print(can_transform("abc", "avc")) # True
print(can_transform('ab', 'abcd')) # False
print(can_transform("avcc", "acc")) # True
Задача №3
# Удалить дубликаты в связанном списке.
# Дан отсортированный по возрастанию связанный список,
# требуется вернуть список без тех элементов, для которых есть дубликаты в исходном.
Пример: [1, 2, 3, 3, 4, 5] -> [1, 2, 4, 5]
Решение:
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
def delete_duplicates(head):
if not head:
return head
dummy = ListNode(0)
dummy.next = head
prev = dummy
current = head
while current:
# Перемещаем указатель до конца участка с одинаковыми значениями
while current.next and current.val == current.next.val:
current = current.next
# Если есть дубликаты, пропускаем их
if prev.next != current:
prev.next = current.next
else:
prev = prev.next
current = current.next
return dummy.next
def print_linked_list(head):
current = head
while current:
print(current.val, end=" -> ")
current = current.next
print("None")
head = ListNode(1)
head.next = ListNode(2)
head.next.next = ListNode(3)
head.next.next.next = ListNode(3)
head.next.next.next.next = ListNode(3)
head.next.next.next.next.next = ListNode(4)
head.next.next.next.next.next.next = ListNode(4)
print("Исходный связанный список:")
print_linked_list(head)
# Удаление дубликатов
head = delete_duplicates(head)
print("Связанный список без дубликатов:")
print_linked_list(head)
Задача №4
Входные данные: Массив пар целочисленных точек на плоскости.
Точки могут повторяться.
Задача: Написать функцию, которая проверяет, обладает ли набор точек свойством центральной симметрии или нет.
Пример:
[(1, 1), (1, 1), (-1, -1)] -> False
[(1, 1), (0, 0), (-1, -1)] -> True
[(1, 1), (1, 0), (1, -1)] -> True
[(1, 1), (-1, -1), (2, 0)] -> False
Решение:
from collections import Counter
def has_central_symmetry(points):
if not points:
return True
counts = Counter(points)
twice_x = min(x for x, y in points) + max(x for x, y in points)
twice_y = min(y for x, y in points) + max(y for x, y in points)
return all(counts[(twice_x - x, twice_y - y)] == count
for (x, y), count in counts.items())
# Пустой набор считаем симметричным. Повторы учитываются по кратности.
Задача №5
Даны 2 отсортированных в порядке возрастания списка с целыми числами. Например:
[-10, -10, 1, 1, 1, 5, 5, 8, 22]
[-20, -10, 8,8,8,22, 22]
нужно разработать алгоритм, который принимает на вход эти два списка, а на выход
выдает их сортированное пересечение без дублей. Для примера выше, результат будет:
[-10, 8, 22]
Ограничения по времени: O(сумма длин списков)
Ограничения по памяти: O(1) без учета памяти на результирующий список
Ограничения по операциям: нельзя пользоваться set(), dict()
def unique_intersection(left: List[int], right: List[int]) -> List[int]:
result = []
# PLACE FOR YOUR CODE
return result
Решение:
from typing import List
def unique_intersection(left: List[int], right: List[int]) -> List[int]:
result = []
i, j = 0, 0 # Указатели для списков left и right соответственно
while i < len(left) and j < len(right):
if left[i] == right[j]:
# Добавляем элемент в результат только если это первое вхождение данного значения
if not result or left[i] != result[-1]:
result.append(left[i])
i += 1
j += 1
elif left[i] < right[j]:
i += 1
else:
j += 1
return result
# Пример использования
left = [-10, -10, 1, 1, 1, 5, 5, 8, 22]
right = [-20, -10, 8, 8, 8, 22, 22]
print(unique_intersection(left, right)) # [-10, 8, 22]
Задача №6
Дан список интов, повторяющихся элементов в списке нет.
Нужно преобразовать это множество в строку, сворачивая соседние по числовому ряду числа в диапазоны.
Примеры:
[1,4,5,2,3,9,8,11,0] => "0-5,8-9,11"
[1,4,3,2] => "1-4"
[1,4] => "1,4"
Решение:
def compress_ranges(nums):
if not nums:
return ""
nums.sort() # Сортируем список чисел
result = []
start = end = nums[0] # Начальное значение диапазона
for num in nums[1:]:
if num == end + 1:
end = num # Расширяем текущий диапазон
else:
# Если диапазон состоит из одного числа, добавляем его в результат как строку
if start == end:
result.append(str(start))
else:
# Если диапазон состоит из нескольких чисел, добавляем его в результат в виде диапазона
result.append(f"{start}-{end}")
start = end = num # Начинаем новый диапазон
# Добавляем последний диапазон в результат
if start == end:
result.append(str(start))
else:
result.append(f"{start}-{end}")
# Объединяем все части результата в одну строку
return ",".join(result)
# Примеры использования
print(compress_ranges([1, 4, 5, 2, 3, 9, 8, 11, 0])) # "0-5,8-9,11"
print(compress_ranges([1, 4, 3, 2])) # "1-4"
print(compress_ranges([1, 4])) # "1,4"
Задача №7
Дана строка, необходимо найти символ, который встречается подряд максимальное число раз.
Пример: bbccccbbbdd -> c
Space = O(1); Time = O(n)
Решение:
def max_consecutive_char(s):
if not s:
return None
max_count = 1
max_char = s[0]
current_count = 1
for i in range(1, len(s)):
if s[i] == s[i - 1]:
current_count += 1
if current_count > max_count:
max_count = current_count
max_char = s[i]
else:
current_count = 1
return max_char
# Пример использования
print(max_consecutive_char("bbccccbbbdd")) # c
Задача №8
Дан массив строк, нужно сгруппировать в нем анаграммы.
Слово X является анаграммой слова Y, если оно может быть получено из другого перестановкой букв.
group_anagrams(["ate", "tea", "tan", "nat"]) -> [["ate", "tea"], ["tan", "nat"]]
Решение:
def group_anagrams(words):
anagrams = {}
# Проходим по каждому слову в списке
for word in words:
# Сортируем буквы слова, чтобы получить ключ
sorted_word = "".join(sorted(word))
# Добавляем слово в соответствующую группу анаграмм
if sorted_word in anagrams:
anagrams[sorted_word].append(word)
else:
anagrams[sorted_word] = [word]
# Преобразуем словарь в список списков
result = list(anagrams.values())
return result
# Пример использования
print(group_anagrams(["ate", "tea", "tan", "nat"]))
Задача №9
Написать class RandomizedSet.
С точки зрения пользователя объект этого класса хранит уникальный набор элементов,
можно добавить элемент или удалить. Так же можно равноверятно получить один из элементов.
randomized_set = RandomizedSet() randomized_set.add(1) randomized_set.add(2) randomized_set.add(1)
randomized_set.get_random() --> 1 или 2 с вероятностью ½ randomized_set.get_random() --> 1 или 2 с вероятностью ½
randomized_set.delete(1) randomized_set.get_random() --> 2
Решение:
import random
class RandomizedSet:
def __init__(self):
self.set = set()
self.lst = []
def add(self, val: int) -> bool:
if val not in self.set:
self.set.add(val)
self.lst.append(val)
return True
return False
def remove(self, val: int) -> bool:
if val in self.set:
self.set.remove(val)
self.lst.remove(val)
return True
return False
def get_random(self) -> int:
return random.choice(self.lst)
# Пример использования
randomized_set = RandomizedSet()
randomized_set.add(1)
randomized_set.add(2)
randomized_set.add(1)
print(randomized_set.get_random()) # 1 или 2 с вероятностью 1/2
print(randomized_set.get_random()) # 1 или 2 с вероятностью 1/2
randomized_set.remove(1)
print(randomized_set.get_random()) # 2
Задача №10
Дан список строк.Нужно вывести такие буквы, которые встречаются в КАЖДОЙ из строк списка (включая дубли).
Примеры: ['bella','label','roller'] -> ['e','l','l'] ['cool','lock','cook'] -> ['c','o']
n - максимальная длина слова
Решение:
from collections import Counter
def common_chars(words):
# Получаем список Counter объектов для каждого слова
counts = [Counter(word) for word in words]
# Находим пересечение множеств частот для каждого слова
intersection = counts[0]
for count in counts[1:]:
intersection &= count
# Преобразуем пересечение множеств в список букв
result = []
for char, freq in intersection.items():
result.extend([char] * freq)
return result
# Примеры использования
print(common_chars(['bella','label','roller'])) # ['e', 'l', 'l']
print(common_chars(['cool','lock','cook'])) # ['c', 'o']
Задача №11
На вход функция принимает массив неотсортированных чисел (nums).
Нужно найти начальную и конечную позицию заданного целевого значения (target) для отсортированного массива.
Если цель не найдена в массиве, вернуть [-1, -1].
Пример:
Вход: nums = [8, 8, 7, 10, 5, 7], target = 8
Выход: [3,4]
Вход: nums = [], target = 0
Выход: [-1,-1]
Решение:
def find_target_index(arr, target):
if target not in arr:
return [-1, -1]
sort_arr = sorted(arr)
res = []
for i, num in enumerate(sort_arr):
if num == target:
res.append(i)
return [res[0], res[-1]]
# Примеры использования
print(find_target_index([8, 8, 7, 10, 5, 7], 8)) # [3, 4]
print(find_target_index([], 0)) # [-1, -1]
Задача №12
Места в кинотеатре расположены в один ряд. Только что пришедший зритель выбирает место,
чтобы сидеть максимально далеко от остальных зрителей в ряду. То есть расстояние от того
места, куда сядет зритель до ближайшего к нему зрителя должно быть максимально.
Гарантируется, что в ряду всегда есть свободные места и уже сидит хотя бы один зритель.
Напишите функцию, которая по заданному ряду мест (массиву из нулей и единиц) вернёт
расстояние от выбранного места до ближайшего зрителя.
Решение:
def max_distance(seats):
max_dist = 0
dist = 0
seated = False
# Проходим по ряду мест
for seat in seats:
if seat == 0: # Если место свободно
dist += 1
else: # Если место занято
if not seated: # Если это первый занятый стул
max_dist = max(max_dist, dist) # Обновляем максимальное расстояние
seated = True
else:
max_dist = max(max_dist, (dist + 1) // 2) # Обновляем максимальное расстояние
dist = 0 # Сбрасываем текущее расстояние
# Обработка случая, когда самое дальнее место свободно
max_dist = max(max_dist, dist)
return max_dist
# Пример использования
print(max_distance([1, 0, 0, 0, 1, 0, 1])) # 2
print(max_distance([1, 0, 0, 0])) # 3
print(max_distance([0, 0, 0, 0, 1])) # 4
Задача №13
Удалить наименьшее количество скобок из строки, чтобы строка стала нормальной скобочной последовательностью
# "[a]]" -> "[a]"
# "[]" -> "[]"
# ][abc][ab[bb]]c][ -> [abc][ab[bb]]c
Решение:
def remove_extra_brackets(s):
unmatched = []
remove = set()
for i, char in enumerate(s):
if char == '[':
unmatched.append(i)
elif char == ']':
if unmatched:
unmatched.pop()
else:
remove.add(i)
remove.update(unmatched)
return ''.join(char for i, char in enumerate(s) if i not in remove)
Задача №14
Подсчитать количество вхождений каждого символа в строке, размер которой превышает объем оперативной памяти.
Решение:
from collections import Counter
def count_characters_large_string(filename):
counts = Counter()
with open(filename, encoding="utf-8") as file:
while chunk := file.read(4096):
counts.update(chunk)
return dict(counts)
# Передайте путь к файлу с текстом, который не помещается в память.
Задача №15
Строка s называется "идеальной", если после "чистки" она становится пустой.
Чисткой называется "схлопывание" двух соседних одинаковых символов, но разного регистра.
Решение:
def clean_string(s):
stack = [] # используем стек для хранения символов перед их схлопыванием
for char in s:
# Если стек не пуст и верхний символ стека схлопывается с текущим символом,
# то удаляем верхний символ из стека
if stack and stack[-1] != char and stack[-1].swapcase() == char:
stack.pop()
else:
stack.append(char) # иначе добавляем текущий символ в стек
return ''.join(stack) # возвращаем строку, оставшуюся в стеке после чистки
def is_perfect_string(s):
return len(clean_string(s)) == 0
s = "abBAcCCc"
print(is_perfect_string(s))
Задача №16
Учитывая массив строк strs, сгруппируйте анаграммы вместе. Вы можете вернуть ответ в любом порядке.
Анаграмма - это слово или фраза, образованные путем перестановки букв другого слова или фразы, обычно используя все исходные буквы ровно один раз.
Input: strs = ["eat","tea","tan","ate","nat","bat"]
Output: [["bat"],["nat","tan"],["ate","eat","tea"]]
Example 2:
Input: strs = [""]
Output: [[""]]
Example 3:
Input: strs = ["a"]
Output: [["a"]]
1 <= strs.length <= 104
0 <= strs[i].length <= 100
strs[i] consists of lowercase English letters.
Решение:
from collections import defaultdict
def group_anagrams(strs):
anagrams = defaultdict(list)
# Группируем слова по отсортированным буквам
for word in strs:
sorted_word = ''.join(sorted(word))
anagrams[sorted_word].append(word)
# Возвращаем только значения (списки слов) из словаря анаграмм
return list(anagrams.values())
strs1 = ["eat", "tea", "tan", "ate", "nat", "bat"]
print(group_anagrams(strs1))
strs2 = [""]
print(group_anagrams(strs2))
strs3 = ["a"]
print(group_anagrams(strs3))
Задача №17
У нас есть список чисел, отсортированный по возрастанию.
Нам нужно вернуть список квадратов этих чисел, также отсортированных по возрастанию.
Решение:
def sorted_squares(nums):
n = len(nums)
result = [0] * n
left, right = 0, n - 1
index = n - 1
while left <= right:
left_square = nums[left] ** 2
right_square = nums[right] ** 2
if left_square > right_square:
result[index] = left_square
left += 1
else:
result[index] = right_square
right -= 1
index -= 1
return result
nums = [-4, 0, 1, 5, 12]
print(sorted_squares(nums))
Задача №18
Дан список чисел. Требуется вычислить произведение всех элементов списка,
за исключением элемента на позиции i, и поместить результат на соответствующую позицию в новом списке.
Решение:
def productExceptSelf(nums):
prod = [0] * len(nums)
left = [0] * len(nums)
right = [0] * len(nums)
left[0], right[len(nums) - 1] = 1, 1
for i in range(1, len(nums)):
left[i] = nums[i - 1] * left[i - 1]
for j in range(len(nums) - 2, -1, -1):
right[j] = nums[j + 1] * right[j + 1]
for i in range(len(nums)):
prod[i] = left[i] * right[i]
return prod
arr = [1, 2, 3, 0, -5]
print(productExceptSelf(arr))
Задача №19
Вам будет предоставлен отсортированный уникальный массив целых чисел nums.
Диапазон [a,b] - это набор всех целых чисел от a до b (включительно).
Возвращает наименьший отсортированный список диапазонов, которые точно охватывают все числа в массиве.
То есть каждый элемент nums покрывается ровно одним из диапазонов, и не существует целого числа, x такого,
x которое находится в одном из диапазонов, но не в nums.
Каждый диапазон [a,b] в списке должен быть выведен как:
"a->b" если a != b
"a" если a == b
Пример 1:
Входные данные: nums = [0,1,2,4,5,7]Вывод: ["0->2","4->5","7"]
Пояснение: Диапазоны следующие:
[0,2] --> "0->2"
[4,5] --> "4->5"
[7,7] --> "7"
Пример 2:
Входные данные: nums = [0,2,3,4,6,8,9]
Вывод: ["0","2->4","6","8->9"]
Пояснение: Диапазоны следующие:
[0,0] --> "0"
[2,4] --> "2->4"
[6,6] --> "6"
[8,9] --> "8->9"
Ограничения:
0 <= nums.length <= 20
-231 <= nums[i] <= 231 - 1
Все значения nums являются уникальными.
nums отсортированы в порядке возрастания.
Решение:
def find_ranges(nums):
if not nums:
return []
ranges = []
start = end = nums[0]
for num in nums[1:]:
if num == end + 1:
end = num
else:
ranges.append(format_range(start, end))
start = end = num
ranges.append(format_range(start, end))
return ranges
def format_range(start, end):
if start == end:
return str(start)
else:
return str(start) + "->" + str(end)
Задача №20
У вас есть двумерный список с целыми числами (каждая ячейка содержит номер цвета).
На вход подаются координаты точки и цвет.
Необходимо заливать смежную с заданной точкой область выбранным цветом.
Решение:
def flood_fill(image, sr, sc, new_color):
if not image:
return image
rows, cols = len(image), len(image[0])
start_color = image[sr][sc]
if start_color == new_color:
return image
queue = [(sr, sc)]
while queue:
row, col = queue.pop(0)
image[row][col] = new_color
# Проверяем смежные точки и добавляем их в очередь, если их цвет совпадает с начальным цветом
for dr, dc in [(1, 0), (-1, 0), (0, 1), (0, -1)]:
r, c = row + dr, col + dc
if 0 <= r < rows and 0 <= c < cols and image[r][c] == start_color:
queue.append((r, c))
return image
image = [
[1, 1, 1, 1],
[1, 1, 0, 0],
[1, 0, 1, 1]
]
sr, sc = 1, 1 # Координаты начальной точки
new_color = 2 # Новый цвет для заливки
print(flood_fill(image, sr, sc, new_color))
Задача №21
Что вернет? Как это исправить?
def append(element, seq=[]):
seq.append(element)
return seq
Решение:
# При вызове предыдущей функции будет использоваться один и тот же список seq.
# Чтобы это исправить, нужно сделать seq=None, и сделать проверку seq is None
def append(element, seq=None):
if seq is None:
seq = []
seq.append(element)
return seq
Задача №22
Вам предоставлены два массива целых чисел nums1 и nums2, отсортированные в неубывающем порядке,
и два целых числа m и n, представляющих количество элементов в nums1 и nums2 соответственно.
Объединить nums1 и nums2 в единый массив, отсортированный в неубывающем порядке.
Окончательный отсортированный массив не должен быть возвращен функцией, но вместо этого должен быть сохранен внутри массива nums1.
Чтобы учесть это, nums1 имеет длину m + n, где первые m элементы обозначают элементы, которые должны быть объединены, а последние
n элементы имеют значение 0 и их следует игнорировать. nums2 имеет длину n.
Пример 1:
Входные данные: nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3 Вывод: [1,2,2,3,5,6]
Объяснение: Объединяемыми массивами являются [1,2,3] и [2,5,6].
Результатом слияния является [1,2,2,3, 5,6] с подчеркнутыми элементами, взятыми из nums1.
Пример 2:
Входные данные: nums1 = [1], m = 1, nums2 = [], n = 0
Выходные данные: [1]
Пояснение: Объединяемыми массивами являются [1] и [].
Результатом слияния является [1].
Пример 3:
Входные данные: nums1 = [0], m = 0, nums2 = [1], n = 1
Выходные данные: [1]
Объяснение: Объединяемыми массивами являются [] и [1].
Результатом слияния является [1].
Обратите внимание, что, поскольку m = 0, в nums1 нет элементов. 0 указано только для того, чтобы результат слияния поместился в nums1.
Ограничения:
nums1.length == m + nnums2.length == n0 <= m, n <= 2001 <= m + n <= 200-109 <= nums1[i], nums2[j] <= 109
Продолжение: Можете ли вы придумать алгоритм, который выполняется за O(m + n) время?
Решение:
def merge(nums1, m, nums2, n):
p1, p2 = m - 1, n - 1
p = m + n - 1
while p1 >= 0 and p2 >= 0:
if nums1[p1] > nums2[p2]:
nums1[p] = nums1[p1]
p1 -= 1
else:
nums1[p] = nums2[p2]
p2 -= 1
p -= 1
# Если в nums2 остались элементы, добавляем их в nums1
nums1[:p2 + 1] = nums2[:p2 + 1]
nums1_1 = [1, 2, 3, 0, 0, 0]
m_1 = 3
nums2_1 = [2, 5, 6]
n_1 = 3
merge(nums1_1, m_1, nums2_1, n_1)
print(nums1_1) # Output: [1, 2, 2, 3, 5, 6]
nums1_2 = [1]
m_2 = 1
nums2_2 = []
n_2 = 0
merge(nums1_2, m_2, nums2_2, n_2)
print(nums1_2) # Output: [1]
nums1_3 = [0]
m_3 = 0
nums2_3 = [1]
n_3 = 1
merge(nums1_3, m_3, nums2_3, n_3)
print(nums1_3) # Output: [1]
Задача №23
Написать функцию для рассчета факториала числа.
Решение:
def factorial(n):
if n < 0:
raise ValueError("n must be non-negative")
result = 1
for value in range(2, n + 1):
result *= value
return result
Задача №24
Есть список
l = [3, 2, 2, 3, 4, 1, 1, 2, 2, 4, 4] и число N.
Нужно в том же порядке вывести элементы списка, но чтобы каждое число повторялось не более N раз
Решение:
def print_repeated_elements(l, N):
counter = {}
output = ""
for num in l:
if num not in counter:
counter[num] = 1
else:
counter[num] += 1
if counter[num] <= N:
output += str(num) + " "
print(output.strip())
Задача №25
Можно ли преобразовать первую строку во вторую не более чем за m операций? Разрешены вставка, удаление и замена одного символа; строки могут иметь разную длину. Разность длин даёт нижнюю границу числа операций, но не заменяет вычисление расстояния редактирования.
Решение:
def can_convert_strings(s1, s2, m):
if m < 0 or abs(len(s1) - len(s2)) > m:
return False
previous = list(range(len(s2) + 1))
for i, c1 in enumerate(s1, 1):
current = [i]
for j, c2 in enumerate(s2, 1):
current.append(min(previous[j] + 1, current[j - 1] + 1,
previous[j - 1] + (c1 != c2)))
previous = current
return previous[-1] <= m
Задача №26
Задачка про сумму всего листа кроме i-ого элемента.
Решение:
def sum_except_i(lst):
result = []
total_sum = sum(lst)
for i in range(len(lst)):
result.append(total_sum - lst[i])
return result
Задача №27
Дан массив целых чисел, отсортированный по возрастанию.
Вернуть массив, содержащий элементы исходного массива в квадрате, также отсортированный по возрастанию.
sortedSquares [1, 4, 10]) → [1, 16, 100]
sortedSquares ([-5, -3, 0, 1, 2, 4]) → [0, 1, 4, 9, 16, 25]
Решение:
def sortedSquares(nums):
n = len(nums)
result = [0] * n
left, right = 0, n - 1
index = n - 1
while left <= right:
left_square = nums[left] * nums[left]
right_square = nums[right] * nums[right]
if left_square > right_square:
result[index] = left_square
left += 1
else:
result[index] = right_square
right -= 1
index -= 1
return result
Задача №28
Напишите стек, который поддерживает следующие операции:
push(x) - кладет элемент на стек
pop() - удаляет и возвращает элемент со стека
getMin() - возвращает значение минимального элемента в стеке
Методы рор и getMin вызываются всегда для непустого стека.
MinStack minStack = new MinStack();
minStack. push(-2); minStack. push(0); minStack. push(-3);
minStack.getMin(); // return -3 minStack. pop();
minStack.getMin(); // return -2
Решение:
class MinStack:
def __init__(self):
self.stack = []
self.min_stack = []
def push(self, x):
self.stack.append(x)
if not self.min_stack or x <= self.min_stack[-1]:
self.min_stack.append(x)
def pop(self):
if self.stack[-1] == self.min_stack[-1]:
self.min_stack.pop()
return self.stack.pop()
def getMin(self):
return self.min_stack[-1]
Задача №29
Дан двумерный список defaults, где каждый элемент defaults[i] = [[start_i], [end_i]] обозначает год начала и окончания дефолта i-го клиента.
Клиент учитывается в году x, если x попадает включительно в диапазон [start, end - 1].
Клиент не учитывается в году, в котором вышел из дефолта.
Найти самый ранний год с максимальным количеством дефолтов.
defaults = [[1950, 1961], [1960, 1971], [1970, 1981]]
Вывод: 1960.
Максимум 2, и он случился в 1960 и 1970. Ранний год среди них – 1960.
Решение:
def earliest_max_defaults(defaults):
# Создаем словарь для подсчета дефолтов для каждого года
year_counts = {}
max_count = 0
# Проходим по списку дефолтов и увеличиваем счетчик для каждого года в диапазоне
for default in defaults:
start_year, end_year = default
for year in range(start_year, end_year):
year_counts[year] = year_counts.get(year, 0) + 1
max_count = max(max_count, year_counts[year])
# Находим самый ранний год с максимальным количеством дефолтов
earliest_year = float('inf')
for year, count in year_counts.items():
if count == max_count:
earliest_year = min(earliest_year, year)
return earliest_year
Задача №30
Дан список с числами.
Надо вывести количество пар хороших чисел.
Хорошей парой называют такую пару что nums[i] == nums[j], i>j.
Как пример был [1,1,1,1] -> result 6 (пары - (0,1),(0,2),(0,3),(1,2),(1,3), (2,3)) в скобках индексы.
Решение:
def good_pairs(nums):
num_counts = {} # Словарь для подсчета количества встреч каждого числа
pairs = 0 # Счетчик хороших пар
for num in nums:
if num in num_counts:
pairs += num_counts[num] # Увеличиваем счетчик пар на количество предыдущих встреч числа
num_counts[num] += 1 # Увеличиваем количество встреч числа в словаре
else:
num_counts[num] = 1 # Добавляем число в словарь с количеством встреч равным 1
return pairs
Задача №31
# На вход подается строка вида
'key1:value1:key2:value2:key3::key4:value4'
# Не для каждого ключа может быть значение или оно может быть пустым.
# Задача: написать функцию, которая превратит эту строку в словарь, с условием того,
# чтобы из этого словаря можно было собрать исходную строку обратно.
Решение:
def string_to_dict(s):
parts = s.split(":")
result = {}
for i in range(0, len(parts), 2):
key = parts[i]
if i + 1 < len(parts):
value = parts[i + 1]
else:
value = None
result[key] = value
return result
def dict_to_string(d):
parts = []
for key, value in d.items():
if value is not None:
parts.append(key + ":" + value)
else:
parts.append(key)
return ":".join(parts)
Задача №32
# Условие:
# Дана строка, состоящая из букв 'X', 'Y' и 'O'.
# Необходимо найти кратчайшее расстояние между буквами 'X' и 'Y',
# либо вывести 0, если 'X' либо 'Y' отсутствуют.
# "YY" -> 0
# "XX" -> 0
# "XOOOOOOX" -> 0
# "OOOOOYOOOOOOYOO" -> 0
# "OOOOOOO" -> 0
# "XY" -> 1
# "YOX" -> 2
# "OOOXOOYOXO" -> 2
# "OOOXXOYOO"-> 2
# "XYXOOYOXOY" -> 1
x_p, y_p
Решение:
def shortest_distance(s):
x_pos = -1
y_pos = -1
min_distance = len(s)
for i, char in enumerate(s):
if char == 'X':
x_pos = i
elif char == 'Y':
y_pos = i
if x_pos != -1 and y_pos != -1:
min_distance = min(min_distance, abs(x_pos - y_pos))
return min_distance if min_distance < len(s) else 0
Задача №33
Напишите собственный декоратор.
Решение:
def simple_decorator(func):
def wrapper(*args, **kwargs):
print("Before function execution")
result = func(*args, **kwargs)
print("After function execution")
return result
return wrapper
# Пример использования декоратора
@simple_decorator
def example_function(x, y):
return x + y
# Вызов функции с декоратором
print(example_function(3, 5))
Задача №34
Дана строка s и символ c, который содержится в s.
Необходимо вернуть массив чисел такой же длины как s, где каждое число равно расстоянию i-й буквы до ближайшего вхождения символа c в строке.
Расстояние между двумя индексами в массиве i и j будем считать как |i - j|. Как минимум один элемент с есть в строке s
Решение:
def shortest_to_char(s, c):
n = len(s)
result = [0] * n
prev_c = float('-inf')
# Проходим слева направо, обновляя результат для каждой буквы
for i in range(n):
if s[i] == c:
prev_c = i
result[i] = i - prev_c
# Проходим справа налево, чтобы учесть ближайшее вхождение справа
prev_c = float('inf')
for i in range(n - 1, -1, -1):
if s[i] == c:
prev_c = i
result[i] = min(result[i], prev_c - i)
return result
s = "loveleetcode"
c = "e"
print(shortest_to_char(s, c))
Задача №35
Можно ли подать пустой лист в функцию, как значение аргумента по умолчанию?
Решение:
# Да, можно, но лучше использовать None вместо изменяемых объектов в качестве значений по умолчанию.
def func(lst=[]):
for item in lst:
print(item)
func()