Решение задач с LeetCode TOP-150 (Блок 4/5: Задачи 91-120)
91. Clone Graph
Описание: Клонировать неориентированный граф.
class Node:
def __init__(self, val = 0, neighbors = None):
self.val = val
self.neighbors = neighbors if neighbors is not None else []
def cloneGraph(node):
"""
Клонирование неориентированного графа
"""
if not node:
return None
# Словарь для хранения копий узлов
clones = {}
def dfs(original):
"""Рекурсивно клонируем граф"""
if original in clones:
return clones[original]
# Создаем копию узла
clone = Node(original.val)
clones[original] = clone
# Рекурсивно клонируем соседей
for neighbor in original.neighbors:
clone.neighbors.append(dfs(neighbor))
return clone
return dfs(node)
# Итеративное решение
def cloneGraphIterative(node):
if not node:
return None
clones = {node: Node(node.val)}
stack = [node]
while stack:
current = stack.pop()
for neighbor in current.neighbors:
if neighbor not in clones:
clones[neighbor] = Node(neighbor.val)
stack.append(neighbor)
clones[current].neighbors.append(clones[neighbor])
return clones[node]
92. Evaluate Division
Описание: Вычислить результаты уравнений вида a/b = values[i].
from collections import defaultdict, deque
def calcEquation(equations, values, queries):
"""
Вычисление результатов уравнений
"""
# Строим граф отношений
graph = defaultdict(dict)
for (a, b), value in zip(equations, values):
graph[a][b] = value # a / b = value
graph[b][a] = 1.0 / value # b / a = 1/value
def bfs(start, end):
"""Поиск пути от start до end"""
if start not in graph or end not in graph:
return -1.0
if start == end:
return 1.0
queue = deque([(start, 1.0)]) # (node, текущий продукт)
visited = set([start])
while queue:
node, product = queue.popleft()
if node == end:
return product
for neighbor, value in graph[node].items():
if neighbor not in visited:
visited.add(neighbor)
queue.append((neighbor, product * value))
return -1.0
# Обрабатываем все запросы
results = []
for a, b in queries:
results.append(bfs(a, b))
return results
93. Course Schedule
Описание: Проверить возможность завершения всех курсов (задача о цикле в графе).
def canFinish(numCourses, prerequisites):
"""
Проверка возможности завершения всех курсов (топологическая сортировка)
"""
# Строим граф и считаем входящие степени
graph = [[] for _ in range(numCourses)]
indegree = [0] * numCourses
for course, prereq in prerequisites:
graph[prereq].append(course)
indegree[course] += 1
# Находим узлы с нулевой входящей степенью
queue = deque([i for i in range(numCourses) if indegree[i] == 0])
completed = 0
while queue:
course = queue.popleft()
completed += 1
# Уменьшаем входящую степень соседей
for neighbor in graph[course]:
indegree[neighbor] -= 1
if indegree[neighbor] == 0:
queue.append(neighbor)
return completed == numCourses
94. Course Schedule II
Описание: Найти порядок прохождения курсов.
def findOrder(numCourses, prerequisites):
"""
Нахождение порядка прохождения курсов
"""
# Строим граф
graph = [[] for _ in range(numCourses)]
indegree = [0] * numCourses
for course, prereq in prerequisites:
graph[prereq].append(course)
indegree[course] += 1
# Топологическая сортировка
queue = deque([i for i in range(numCourses) if indegree[i] == 0])
order = []
while queue:
course = queue.popleft()
order.append(course)
for neighbor in graph[course]:
indegree[neighbor] -= 1
if indegree[neighbor] == 0:
queue.append(neighbor)
# Проверяем, что все курсы пройдены
if len(order) == numCourses:
return order
else:
return []
95. Snakes and Ladders
Описание: Найти минимальное количество ходов в игре "Змеи и лестницы".
def snakesAndLadders(board):
"""
Минимальное количество ходов в игре "Змеи и лестницы"
"""
n = len(board)
def get_position(square):
"""Преобразует номер клетки в координаты на доске"""
row = (square - 1) // n
col = (square - 1) % n
# Нечетные строки идут справа налево
if row % 2 == 1:
col = n - 1 - col
# Нумерация строк снизу вверх
row = n - 1 - row
return row, col
# BFS для поиска кратчайшего пути
visited = [False] * (n * n + 1)
queue = deque([(1, 0)]) # (квадрат, ходы)
visited[1] = True
while queue:
square, moves = queue.popleft()
# Достигли цели
if square == n * n:
return moves
# Пытаемся сделать от 1 до 6 шагов
for step in range(1, 7):
next_square = square + step
if next_square > n * n:
break
# Получаем координаты на доске
r, c = get_position(next_square)
# Если есть змея или лестница
if board[r][c] != -1:
next_square = board[r][c]
# Если еще не посещали эту клетку
if not visited[next_square]:
visited[next_square] = True
queue.append((next_square, moves + 1))
return -1
96. Minimum Genetic Mutation
Описание: Найти минимальное количество мутаций для преобразования одной строки ДНК в другую.
from collections import deque
def minMutation(startGene, endGene, bank):
"""
Минимальное количество мутаций для преобразования гена
"""
# Преобразуем bank в множество для быстрого поиска
bank_set = set(bank)
if endGene not in bank_set:
return -1
# Возможные мутации для каждого положения
mutations = ['A', 'C', 'G', 'T']
# BFS для поиска кратчайшего пути
queue = deque([(startGene, 0)])
visited = set([startGene])
while queue:
gene, steps = queue.popleft()
if gene == endGene:
return steps
# Генерируем все возможные мутации
for i in range(len(gene)):
for mut in mutations:
if mut == gene[i]:
continue
# Создаем новую строку с мутацией
new_gene = gene[:i] + mut + gene[i+1:]
if new_gene in bank_set and new_gene not in visited:
visited.add(new_gene)
queue.append((new_gene, steps + 1))
return -1
97. Word Ladder
Описание: Найти кратчайшую последовательность преобразований от одного слова к другому.
from collections import deque
from typing import List
def ladderLength(beginWord: str, endWord: str, wordList: List[str]) -> int:
"""
Кратчайшая последовательность преобразований слов
"""
word_set = set(wordList)
if endWord not in word_set:
return 0
# BFS для поиска кратчайшего пути
queue = deque([(beginWord, 1)])
visited = set([beginWord])
while queue:
word, length = queue.popleft()
if word == endWord:
return length
# Генерируем все возможные преобразования
for i in range(len(word)):
for c in 'abcdefghijklmnopqrstuvwxyz':
if c == word[i]:
continue
new_word = word[:i] + c + word[i+1:]
if new_word in word_set and new_word not in visited:
visited.add(new_word)
queue.append((new_word, length + 1))
return 0
98. Implement Trie (Prefix Tree)
Описание: Реализовать структуру данных Trie (префиксное дерево).
class TrieNode:
def __init__(self):
self.children = {}
self.is_end = False
class Trie:
def __init__(self):
"""
Инициализация Trie
"""
self.root = TrieNode()
def insert(self, word: str) -> None:
"""
Вставка слова в Trie
"""
node = self.root
for char in word:
if char not in node.children:
node.children[char] = TrieNode()
node = node.children[char]
node.is_end = True
def search(self, word: str) -> bool:
"""
Поиск слова в Trie
"""
node = self.root
for char in word:
if char not in node.children:
return False
node = node.children[char]
return node.is_end
def startsWith(self, prefix: str) -> bool:
"""
Проверка, есть ли слова с данным префиксом
"""
node = self.root
for char in prefix:
if char not in node.children:
return False
node = node.children[char]
return True
99. Design Add and Search Words Data Structure
Описание: Реализовать структуру данных для добавления и поиска слов с поддержкой '.' как wildcard.
class WordDictionary:
def __init__(self):
"""
Инициализация структуры данных
"""
self.trie = {}
def addWord(self, word: str) -> None:
"""
Добавление слова
"""
node = self.trie
for char in word:
if char not in node:
node[char] = {}
node = node[char]
node['#'] = True # Маркер конца слова
def search(self, word: str) -> bool:
"""
Поиск слова (поддерживает '.' как любой символ)
"""
def search_in_node(word, node):
"""Рекурсивный поиск"""
for i, char in enumerate(word):
if char not in node:
# Если символ '.', проверяем все возможные ветви
if char == '.':
for child in node:
if child != '#' and search_in_node(word[i+1:], node[child]):
return True
return False
else:
node = node[char]
return '#' in node
return search_in_node(word, self.trie)
100. Word Search II
Описание: Найти все слова из списка на игровом поле слов (word search).
class TrieNode:
def __init__(self):
self.children = {}
self.word = None # Храним слово в конце узла
def findWords(board, words):
"""
Поиск всех слов на игровом поле
"""
# Строим Trie из слов
root = TrieNode()
for word in words:
node = root
for char in word:
if char not in node.children:
node.children[char] = TrieNode()
node = node.children[char]
node.word = word
rows, cols = len(board), len(board[0])
result = []
def backtrack(i, j, node):
"""Рекурсивный поиск слов"""
char = board[i][j]
# Проверяем, есть ли такой символ в Trie
if char not in node.children:
return
# Переходим к следующему узлу
next_node = node.children[char]
# Если нашли слово
if next_node.word:
result.append(next_node.word)
next_node.word = None # Предотвращаем дубликаты
# Помечаем ячейку как посещенную
board[i][j] = '#'
# Рекурсивно ищем в соседних ячейках
directions = [(0, 1), (0, -1), (1, 0), (-1, 0)]
for dx, dy in directions:
ni, nj = i + dx, j + dy
if 0 <= ni < rows and 0 <= nj < cols and board[ni][nj] != '#':
backtrack(ni, nj, next_node)
# Восстанавливаем ячейку
board[i][j] = char
# Оптимизация: удаляем листья, которые больше не нужны
if not next_node.children:
del node.children[char]
# Запускаем поиск из каждой ячейки
for i in range(rows):
for j in range(cols):
backtrack(i, j, root)
return result
101. Letter Combinations of a Phone Number
Описание: Сгенерировать все возможные комбинации букв для телефонного номера.
def letterCombinations(digits):
"""
Генерация всех комбинаций букв для телефонного номера
"""
if not digits:
return []
# Соответствие цифр и букв
phone_map = {
'2': 'abc', '3': 'def', '4': 'ghi', '5': 'jkl',
'6': 'mno', '7': 'pqrs', '8': 'tuv', '9': 'wxyz'
}
result = []
def backtrack(index, current):
"""Рекурсивная генерация комбинаций"""
if index == len(digits):
result.append(''.join(current))
return
digit = digits[index]
letters = phone_map[digit]
for letter in letters:
current.append(letter)
backtrack(index + 1, current)
current.pop() # Backtrack
backtrack(0, [])
return result
102. Combinations
Описание: Сгенерировать все комбинации чисел от 1 до n размера k.
def combine(n, k):
"""
Генерация всех комбинаций чисел от 1 до n размера k
"""
result = []
def backtrack(start, current):
"""Рекурсивная генерация комбинаций"""
if len(current) == k:
result.append(current[:])
return
# Оптимизация: не хватает элементов для заполнения
if len(current) + (n - start + 1) < k:
return
for i in range(start, n + 1):
current.append(i)
backtrack(i + 1, current)
current.pop() # Backtrack
backtrack(1, [])
return result
103. Permutations
Описание: Сгенерировать все перестановки массива.
def permute(nums):
"""
Генерация всех перестановок массива
"""
result = []
def backtrack(first):
"""Рекурсивная генерация перестановок"""
if first == len(nums):
result.append(nums[:])
return
for i in range(first, len(nums)):
# Меняем местами
nums[first], nums[i] = nums[i], nums[first]
backtrack(first + 1)
# Возвращаем обратно (backtrack)
nums[first], nums[i] = nums[i], nums[first]
backtrack(0)
return result
# Альтернативное решение с дополнительной памятью
def permute2(nums):
result = []
def backtrack(current, remaining):
if not remaining:
result.append(current[:])
return
for i in range(len(remaining)):
current.append(remaining[i])
backtrack(current, remaining[:i] + remaining[i+1:])
current.pop()
backtrack([], nums)
return result
104. Combination Sum
Описание: Найти все уникальные комбинации чисел, сумма которых равна target.
def combinationSum(candidates, target):
"""
Нахождение всех комбинаций чисел с заданной суммой
"""
result = []
def backtrack(start, current, current_sum):
"""Рекурсивный поиск комбинаций"""
if current_sum == target:
result.append(current[:])
return
if current_sum > target:
return
for i in range(start, len(candidates)):
current.append(candidates[i])
backtrack(i, current, current_sum + candidates[i])
current.pop() # Backtrack
backtrack(0, [], 0)
return result
105. N-Queens II
Описание: Подсчитать количество различных решений задачи N ферзей.
def totalNQueens(n):
"""
Подсчет количества решений задачи N ферзей
"""
def backtrack(row, cols, diag1, diag2):
"""Рекурсивная расстановка ферзей"""
if row == n:
return 1
count = 0
available_positions = ((1 << n) - 1) & (~(cols | diag1 | diag2))
while available_positions:
# Берем младший установленный бит
position = available_positions & -available_positions
available_positions -= position
count += backtrack(
row + 1,
cols | position,
(diag1 | position) << 1,
(diag2 | position) >> 1
)
return count
return backtrack(0, 0, 0, 0)
106. Generate Parentheses
Описание: Сгенерировать все правильные комбинации скобок длины 2n.
def generateParenthesis(n):
"""
Генерация всех правильных комбинаций скобок
"""
result = []
def backtrack(current, open_count, close_count):
"""Рекурсивная генерация скобок"""
if len(current) == 2 * n:
result.append(''.join(current))
return
# Можем добавить открывающую скобку
if open_count < n:
current.append('(')
backtrack(current, open_count + 1, close_count)
current.pop()
# Можем добавить закрывающую скобку
if close_count < open_count:
current.append(')')
backtrack(current, open_count, close_count + 1)
current.pop()
backtrack([], 0, 0)
return result
107. Word Search
Описание: Проверить, существует ли слово на игровом поле букв.
def exist(board, word):
"""
Проверка существования слова на игровом поле
"""
rows, cols = len(board), len(board[0])
def backtrack(i, j, index):
"""Рекурсивный поиск слова"""
# Проверяем границы и совпадение букв
if i < 0 or i >= rows or j < 0 or j >= cols or board[i][j] != word[index]:
return False
# Если это последняя буква слова
if index == len(word) - 1:
return True
# Помечаем ячейку как посещенную
temp = board[i][j]
board[i][j] = '#'
# Ищем следующую букву в соседних ячейках
found = (backtrack(i + 1, j, index + 1) or
backtrack(i - 1, j, index + 1) or
backtrack(i, j + 1, index + 1) or
backtrack(i, j - 1, index + 1))
# Восстанавливаем ячейку
board[i][j] = temp
return found
# Запускаем поиск из каждой ячейки
for i in range(rows):
for j in range(cols):
if backtrack(i, j, 0):
return True
return False
108. Convert Sorted Array to Binary Search Tree
Описание: Преобразовать отсортированный массив в сбалансированное BST.
def sortedArrayToBST(nums):
"""
Преобразование отсортированного массива в сбалансированное BST
"""
def build_tree(left, right):
"""Рекурсивное построение дерева"""
if left > right:
return None
# Средний элемент - корень
mid = (left + right) // 2
root = TreeNode(nums[mid])
# Рекурсивно строим левое и правое поддеревья
root.left = build_tree(left, mid - 1)
root.right = build_tree(mid + 1, right)
return root
return build_tree(0, len(nums) - 1)
109. Sort List
Описание: Отсортировать связный список за O(n log n) времени и O(1) памяти.
def sortList(head):
"""
Сортировка связного списка (merge sort)
"""
if not head or not head.next:
return head
# Находим середину списка
def get_middle(node):
"""Находит середину списка (медленный и быстрый указатель)"""
slow, fast = node, node.next
while fast and fast.next:
slow = slow.next
fast = fast.next.next
return slow
# Слияние двух отсортированных списков
def merge(left, right):
"""Слияние двух отсортированных списков"""
dummy = ListNode(0)
current = dummy
while left and right:
if left.val <= right.val:
current.next = left
left = left.next
else:
current.next = right
right = right.next
current = current.next
# Добавляем оставшиеся узлы
if left:
current.next = left
if right:
current.next = right
return dummy.next
# Рекурсивная сортировка
mid = get_middle(head)
right_head = mid.next
mid.next = None # Разделяем список
left = sortList(head)
right = sortList(right_head)
return merge(left, right)
110. Construct Quad Tree
Описание: Построить Quad Tree из бинарной матрицы.
class Node:
def __init__(self, val, isLeaf, topLeft, topRight, bottomLeft, bottomRight):
self.val = val
self.isLeaf = isLeaf
self.topLeft = topLeft
self.topRight = topRight
self.bottomLeft = bottomLeft
self.bottomRight = bottomRight
def construct(grid):
"""
Построение Quad Tree из матрицы
"""
def build(r1, c1, r2, c2):
"""Рекурсивное построение дерева"""
# Проверяем, все ли значения в квадрате одинаковы
all_same = True
first_val = grid[r1][c1]
for i in range(r1, r2):
for j in range(c1, c2):
if grid[i][j] != first_val:
all_same = False
break
if not all_same:
break
# Если все значения одинаковы, создаем лист
if all_same:
return Node(first_val == 1, True, None, None, None, None)
# Иначе делим на 4 части
row_mid = (r1 + r2) // 2
col_mid = (c1 + c2) // 2
topLeft = build(r1, c1, row_mid, col_mid)
topRight = build(r1, col_mid, row_mid, c2)
bottomLeft = build(row_mid, c1, r2, col_mid)
bottomRight = build(row_mid, col_mid, r2, c2)
return Node(False, False, topLeft, topRight, bottomLeft, bottomRight)
n = len(grid)
return build(0, 0, n, n)
111. Merge k Sorted Lists
Описание: Объединить k отсортированных связных списков в один отсортированный список.
import heapq
def mergeKLists(lists):
"""
Объединение k отсортированных связных списков
"""
# Минимальная куча
heap = []
# Добавляем первые элементы каждого списка в кучу
for i, lst in enumerate(lists):
if lst:
heapq.heappush(heap, (lst.val, i, lst))
dummy = ListNode(0)
current = dummy
while heap:
val, idx, node = heapq.heappop(heap)
# Добавляем узел в результат
current.next = node
current = current.next
# Добавляем следующий элемент из этого списка
if node.next:
heapq.heappush(heap, (node.next.val, idx, node.next))
return dummy.next
112. Maximum Subarray
Описание: Найти подмассив с максимальной суммой (алгоритм Кадане).
def maxSubArray(nums):
"""
Нахождение подмассива с максимальной суммой (алгоритм Кадане)
"""
if not nums:
return 0
max_sum = nums[0]
current_sum = nums[0]
for num in nums[1:]:
# Либо начинаем новый подмассив, либо продолжаем текущий
current_sum = max(num, current_sum + num)
max_sum = max(max_sum, current_sum)
return max_sum
113. Maximum Sum Circular Subarray
Описание: Найти максимальную сумму подмассива в циклическом массиве.
def maxSubarraySumCircular(nums):
"""
Максимальная сумма подмассива в циклическом массиве
"""
# Случай 1: максимальный подмассив не пересекает границу
max_kadane = nums[0]
current_max = nums[0]
total_sum = nums[0]
# Случай 2: минимальный подмассив (для циклического случая)
min_kadane = nums[0]
current_min = nums[0]
for num in nums[1:]:
# Стандартный алгоритм Кадане для максимума
current_max = max(num, current_max + num)
max_kadane = max(max_kadane, current_max)
# Алгоритм Кадане для минимума
current_min = min(num, current_min + num)
min_kadane = min(min_kadane, current_min)
total_sum += num
# Если все числа отрицательные
if max_kadane <= 0:
return max_kadane
# Максимум из обычного подмассива и циклического
return max(max_kadane, total_sum - min_kadane)
114. Search Insert Position
Описание: Найти позицию для вставки элемента в отсортированный массив.
def searchInsert(nums, target):
"""
Поиск позиции для вставки в отсортированный массив
"""
left, right = 0, len(nums) - 1
while left <= right:
mid = (left + right) // 2
if nums[mid] == target:
return mid
elif nums[mid] < target:
left = mid + 1
else:
right = mid - 1
return left
115. Search a 2D Matrix
Описание: Поиск элемента в отсортированной по строкам и столбцам матрице.
def searchMatrix(matrix, target):
"""
Поиск элемента в отсортированной матрице
"""
if not matrix or not matrix[0]:
return False
rows, cols = len(matrix), len(matrix[0])
# Двоичный поиск, рассматривая матрицу как одномерный массив
left, right = 0, rows * cols - 1
while left <= right:
mid = (left + right) // 2
# Преобразуем индекс в координаты
row = mid // cols
col = mid % cols
if matrix[row][col] == target:
return True
elif matrix[row][col] < target:
left = mid + 1
else:
right = mid - 1
return False
116. Find Peak Element
Описание: Найти любой пиковый элемент в массиве.
def findPeakElement(nums):
"""
Поиск пикового элемента в массиве
"""
left, right = 0, len(nums) - 1
while left < right:
mid = (left + right) // 2
if nums[mid] > nums[mid + 1]:
# Пик слева или в середине
right = mid
else:
# Пик справа
left = mid + 1
return left
117. Search in Rotated Sorted Array
Описание: Поиск элемента в отсортированном, но сдвинутом массиве.
def search(nums, target):
"""
Поиск в отсортированном, но сдвинутом массиве
"""
left, right = 0, len(nums) - 1
while left <= right:
mid = (left + right) // 2
if nums[mid] == target:
return mid
# Определяем, какая половина отсортирована
if nums[left] <= nums[mid]:
# Левая половина отсортирована
if nums[left] <= target < nums[mid]:
right = mid - 1
else:
left = mid + 1
else:
# Правая половина отсортирована
if nums[mid] < target <= nums[right]:
left = mid + 1
else:
right = mid - 1
return -1
118. Find First and Last Position of Element in Sorted Array
Описание: Найти первое и последнее вхождение элемента в отсортированном массиве.
def searchRange(nums, target):
"""
Поиск первого и последнего вхождения элемента
"""
def find_left(nums, target):
"""Находит первое вхождение"""
left, right = 0, len(nums) - 1
first = -1
while left <= right:
mid = (left + right) // 2
if nums[mid] >= target:
right = mid - 1
if nums[mid] == target:
first = mid
else:
left = mid + 1
return first
def find_right(nums, target):
"""Находит последнее вхождение"""
left, right = 0, len(nums) - 1
last = -1
while left <= right:
mid = (left + right) // 2
if nums[mid] <= target:
left = mid + 1
if nums[mid] == target:
last = mid
else:
right = mid - 1
return last
first = find_left(nums, target)
last = find_right(nums, target)
return [first, last]
119. Find Minimum in Rotated Sorted Array
Описание: Найти минимальный элемент в отсортированном, но сдвинутом массиве.
def findMin(nums):
"""
Поиск минимального элемента в сдвинутом массиве
"""
left, right = 0, len(nums) - 1
# Массив не сдвинут
if nums[left] < nums[right]:
return nums[left]
while left < right:
mid = (left + right) // 2
if nums[mid] > nums[right]:
# Минимум справа от mid
left = mid + 1
else:
# Минимум слева от mid или в mid
right = mid
return nums[left]
120. Median of Two Sorted Arrays
Описание: Найти медиану двух отсортированных массивов за O(log(min(n,m))).
def findMedianSortedArrays(nums1, nums2):
"""
Поиск медианы двух отсортированных массивов
"""
# Убедимся, что nums1 - меньший массив
if len(nums1) > len(nums2):
nums1, nums2 = nums2, nums1
m, n = len(nums1), len(nums2)
total = m + n
half = total // 2
left, right = 0, m
while left <= right:
# Разбиваем nums1
i = (left + right) // 2
# Разбиваем nums2
j = half - i
# Получаем граничные элементы
nums1_left = nums1[i-1] if i > 0 else float('-inf')
nums1_right = nums1[i] if i < m else float('inf')
nums2_left = nums2[j-1] if j > 0 else float('-inf')
nums2_right = nums2[j] if j < n else float('inf')
# Проверяем правильность разбиения
if nums1_left <= nums2_right and nums2_left <= nums1_right:
# Правильное разбиение
if total % 2 == 1:
# Нечетное количество элементов
return min(nums1_right, nums2_right)
else:
# Четное количество элементов
return (max(nums1_left, nums2_left) + min(nums1_right, nums2_right)) / 2
elif nums1_left > nums2_right:
# Слишком много элементов из nums1 в левой части
right = i - 1
else:
# Слишком мало элементов из nums1 в левой части
left = i + 1
return 0.0
Ключевые моменты четвертого блока:
- Графы и поиск (91-97): BFS, DFS, топологическая сортировка
- Trie и деревья (98-100): Префиксные деревья, поиск слов
- Backtracking (101-107): Комбинации, перестановки, поиск с возвратом
- Divide & Conquer (108-111): Разделяй и властвуй, сортировка слиянием
- Kadane's Algorithm (112-113): Максимальный подмассив
- Binary Search (114-120): Двоичный поиск в различных условиях
Основные алгоритмы:
- Топологическая сортировка для задач расписания
- Backtracking для комбинаторных задач
- Merge Sort для связных списков
- Алгоритм Кадане для максимального подмассива
- Двоичный поиск в различных вариациях