Добавить в корзинуПозвонить
Найти в Дзене
Анастасия Софт

20 сложных задач с собеседований по Python с разбором

Задача: Напишите функцию, которая реверсирует строку без использования срезов или встроенных функций. Решение: def reverse_string(s):
reversed_str = ""
for char in s:
reversed_str = char + reversed_str # Добавляем символ в начало строки
return reversed_str
# Пример использования
print(reverse_string("Python")) # Вывод: "nohtyP" Комментарий: Мы итерируем по строке и добавляем каждый символ в начало новой строки, тем самым инвертируя её. Задача: Напишите функцию, которая проверяет, является ли строка палиндромом (читается одинаково слева направо и справа налево). Решение: def is_palindrome(s):
return s == s[::-1]
# Пример использования
print(is_palindrome("racecar")) # Вывод: True Комментарий: Используем срез для реверсирования строки и сравниваем её с оригиналом. Задача: Напишите функцию, которая подсчитывает количество вхождений элемента в списке. Решение: def count_occurrences(lst, value):
count = 0
for item in lst:
if item == value:
Оглавление
20 сложных задач с собеседований по Python с разбором
20 сложных задач с собеседований по Python с разбором

1. Реверс строки без использования встроенных функций

Задача: Напишите функцию, которая реверсирует строку без использования срезов или встроенных функций.

Решение:

def reverse_string(s):
reversed_str = ""
for char in s:
reversed_str = char + reversed_str # Добавляем символ в начало строки
return reversed_str

# Пример использования
print(reverse_string("Python")) # Вывод: "nohtyP"

Комментарий: Мы итерируем по строке и добавляем каждый символ в начало новой строки, тем самым инвертируя её.

2. Проверка на палиндром

Задача: Напишите функцию, которая проверяет, является ли строка палиндромом (читается одинаково слева направо и справа налево).

Решение:

def is_palindrome(s):
return s == s[::-1]

# Пример использования
print(is_palindrome("racecar")) # Вывод: True

Комментарий: Используем срез для реверсирования строки и сравниваем её с оригиналом.

3. Подсчёт вхождений элемента в списке

Задача: Напишите функцию, которая подсчитывает количество вхождений элемента в списке.

Решение:

def count_occurrences(lst, value):
count = 0
for item in lst:
if item == value:
count += 1
return count

# Пример использования
print(count_occurrences([1, 2, 3, 1, 1], 1)) # Вывод: 3

Комментарий: Итерируем по списку и увеличиваем счётчик при нахождении совпадения.

4. Уникальные элементы списка

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

Решение:

def unique_elements(lst):
return list(set(lst))

# Пример использования
print(unique_elements([1, 2, 2, 3, 4, 4])) # Вывод: [1, 2, 3, 4]

Комментарий: Используем множество для удаления дубликатов, так как множества не содержат повторяющихся элементов.

5. Сортировка списка без использования встроенных функций

Задача: Напишите функцию, которая сортирует список чисел по возрастанию без использования встроенных функций сортировки.

Решение:

def bubble_sort(lst):
n = len(lst)
for i in range(n):
for j in range(0, n-i-1):
if lst[j] > lst[j+1]:
lst[j], lst[j+1] = lst[j+1], lst[j]
return lst

# Пример использования
print(bubble_sort([64, 34, 25, 12, 22, 11, 90])) # Вывод: [11, 12, 22, 25, 34, 64, 90]

Комментарий: Реализуем сортировку пузырьком, сравнивая и меняя местами соседние элементы.

6. Вычисление факториала рекурсивно

Задача: Напишите рекурсивную функцию для вычисления факториала числа.

Решение:

def factorial(n):
if n == 0:
return 1
else:
return n * factorial(n-1)

# Пример использования
print(factorial(5)) # Вывод: 120

Комментарий: Базовый случай — факториал 0 равен 1. Рекурсивно умножаем число на факториал предыдущего.

7. Генератор чисел Фибоначчи

Задача: Напишите генератор, который возвращает числа Фибоначчи.

Решение:

def fibonacci_generator():
a, b = 0, 1
while True:
yield a
a, b = b, a + b

# Пример использования
gen = fibonacci_generator()
for _ in range(10):
print(next(gen), end=" ") # Вывод: 0 1 1 2 3 5 8 13 21 34

Комментарий: Используем yield для создания бесконечного генератора чисел Фибоначчи.

8. Поиск второго по величине числа в списке

Задача: Напишите функцию, которая находит второе по величине число в списке.

Решение:

def second_largest(lst):
unique_lst = list(set(lst)) # Убираем дубликаты
unique_lst.sort()
return unique_lst[-2] if len(unique_lst) > 1 else None

# Пример использования
print(second_largest([1, 2, 3, 4, 5])) # Вывод: 4

Комментарий: Убираем дубликаты, сортируем список и возвращаем предпоследний элемент.

9. Проверка сбалансированности скобок

Задача: Напишите функцию, которая проверяет, правильно ли расставлены скобки в строке.

Решение:

def is_balanced(s):
stack = []
matching_brackets = {')': '(', '}': '{', ']': '['}
for char in s:
if char in matching_brackets.values():
stack.append(char)
elif char in matching_brackets:
if not stack or stack.pop() != matching_brackets[char]:
return False
return not stack

# Пример использования
print(is_balanced("({[()]})")) # Вывод: True

Комментарий: Используем стек для отслеживания открывающихся скобок и проверяем соответствие закрывающих.

10. Подсчёт частоты символов в строке

Задача: Напишите функцию, которая подсчитывает частоту каждого символа в строке.

Решение:

from collections import Counter

def char_frequency(s):
return dict(Counter(s))

# Пример использования
print(char_frequency("hello")) # Вывод: {'h': 1, 'e': 1, 'l': 2, 'o': 1}

Комментарий: Используем Counter из модуля collections для подсчёта частоты символов.

Продолжаем 👇

11. ✅ Проверка на анаграмму

Задача: Проверить, являются ли две строки анаграммами (содержат одинаковые буквы в разном порядке).

Решение:

def is_anagram(s1, s2):
return sorted(s1) == sorted(s2)

# Пример использования
print(is_anagram("listen", "silent")) # Вывод: True

Комментарий: Просто сортируем обе строки и сравниваем — если в них одинаковые буквы, отсортированные списки совпадут.

12. 🧠 Поиск всех пар с заданной суммой

Задача: Найти все пары чисел в списке, которые в сумме дают заданное число.

def find_pairs(lst, target):
seen = set()
pairs = set()
for num in lst:
diff = target - num
if diff in seen:
pairs.add((min(num, diff), max(num, diff))) # упорядочим пары
seen.add(num)
return list(pairs)

# Пример использования
print(find_pairs([1, 2, 3, 4, 5], 6)) # Вывод: [(1, 5), (2, 4)]

Комментарий: Используем множество для запоминания уже просмотренных чисел. Пары сохраняем в виде кортежей (упорядоченных), чтобы избежать дубликатов.

13. 📐 Нахождение самого длинного слова в строке

Задача: Вернуть самое длинное слово из строки.

def longest_word(s):
words = s.split()
return max(words, key=len)

# Пример использования
print(longest_word("I love programming in Python")) # Вывод: "programming"

Комментарий: Разбиваем строку по пробелам и ищем максимум по длине.

14. 🔁 Рекурсивный вывод чисел от N до 0

def countdown(n):
if n < 0:
return
print(n)
countdown(n - 1)

# Пример использования
countdown(5)

Комментарий: Классический пример рекурсии, просто уменьшаем n до тех пор, пока не достигнем отрицательного числа.

15. 📊 Группировка слов по анаграммам

Задача: Из списка слов сгруппировать слова, являющиеся анаграммами.

from collections import defaultdict

def group_anagrams(words):
result = defaultdict(list)
for word in words:
key = ''.join(sorted(word)) # сортируем слово, чтобы сравнить
result[key].append(word)
return list(result.values())

# Пример использования
print(group_anagrams(["eat", "tea", "tan", "ate", "nat", "bat"]))
# Вывод: [['eat', 'tea', 'ate'], ['tan', 'nat'], ['bat']]

Комментарий: Используем отсортированное слово как ключ, чтобы сгруппировать все его перестановки.

16. 🎛️ Перестановки строки (рекурсивно)

def permutations(s):
if len(s) <= 1:
return [s]
result = []
for i, char in enumerate(s):
for perm in permutations(s[:i] + s[i+1:]):
result.append(char + perm)
return result

# Пример использования
print(permutations("abc"))
# Вывод: ['abc', 'acb', 'bac', 'bca', 'cab', 'cba']

Комментарий: Классическая задача на рекурсию — разбиваем строку, фиксируем символ и вызываем перестановки от оставшихся.

17. 🧮 Быстрое возведение в степень (без **)

def power(a, b):
if b == 0:
return 1
half = power(a, b // 2)
return half * half if b % 2 == 0 else a * half * half

# Пример использования
print(power(2, 10)) # Вывод: 1024

Комментарий: Используем «разделяй и властвуй» для сокращения количества умножений до O(log b).

18. 🧪 Проверка на простое число

def is_prime(n):
if n <= 1:
return False
for i in range(2, int(n**0.5)+1):
if n % i == 0:
return False
return True

# Пример использования
print(is_prime(29)) # Вывод: True

Комментарий: Проверка до √n — минимально необходимый набор делений, чтобы определить простоту числа.

19. 🔁 Поиск самого длинного подстрочного палиндрома

def longest_palindrome(s):
result = ""
for i in range(len(s)):
for j in range(i, len(s)):
temp = s[i:j+1]
if temp == temp[::-1] and len(temp) > len(result):
result = temp
return result

# Пример использования
print(longest_palindrome("babad")) # Вывод: "bab" или "aba"

Комментарий: Перебираем все подстроки и проверяем, палиндром ли они. Неэффективно, но работает.

20. 💡 LRU Cache (на собеседованиях любят)

from collections import OrderedDict

class LRUCache:
def __init__(self, capacity):
self.cache = OrderedDict()
self.capacity = capacity

def get(self, key):
if key not in self.cache:
return -1
self.cache.move_to_end(key) # Обновляем "последнее использование"
return self.cache[key]

def put(self, key, value):
if key in self.cache:
self.cache.move_to_end(key)
self.cache[key] = value
if len(self.cache) > self.capacity:
self.cache.popitem(last=False) # Удаляем самый старый элемент

# Пример использования
lru = LRUCache(2)
lru.put(1, 1)
lru.put(2, 2)
print(lru.get(1)) # Вывод: 1
lru.put(3, 3)
print(lru.get(2)) # Вывод: -1, т.к. он удалён из-за лимита

Комментарий: Используем OrderedDict, который сохраняет порядок вставки и позволяет эффективно удалять старейшие элементы.