This commit is contained in:
krahets
2026-03-29 05:06:58 +08:00
parent 37523d4ceb
commit 967293c421
51 changed files with 288 additions and 5073 deletions
@@ -307,12 +307,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="array.rb" ```ruby title="array.rb"
=begin
File: array.rb
Created Time: 2024-03-18
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
### Случайный доступ к элементу ### ### Случайный доступ к элементу ###
def random_access(nums) def random_access(nums)
# Случайным образом выбрать число из интервала [0, nums.length) # Случайным образом выбрать число из интервала [0, nums.length)
@@ -507,38 +501,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="array.rb" ```ruby title="array.rb"
=begin
File: array.rb
Created Time: 2024-03-18
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
# ## Случайный доступ к элементу ###
def random_access(nums)
# Случайным образом выбрать число из интервала [0, nums.length)
random_index = Random.rand(0...nums.length)
# Получить и вернуть случайный элемент
nums[random_index]
end
# ## Увеличить длину массива ###
# Обратите внимание: Array в Ruby является динамическим массивом и может быть расширен напрямую
# Для удобства обучения эта функция рассматривает Array как массив неизменяемой длины
def extend(nums, enlarge)
# Инициализировать массив увеличенной длины
res = Array.new(nums.length + enlarge, 0)
# Скопировать все элементы исходного массива в новый массив
for i in 0...nums.length
res[i] = nums[i]
end
# Вернуть новый массив после расширения
res
end
### Вставка элемента num по индексу index в массив ### ### Вставка элемента num по индексу index в массив ###
def insert(nums, num, index) def insert(nums, num, index)
# Сдвинуть элемент с индексом index и все последующие элементы на одну позицию назад # Сдвинуть элемент с индексом index и все последующие элементы на одну позицию назад
@@ -712,50 +674,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="array.rb" ```ruby title="array.rb"
=begin
File: array.rb
Created Time: 2024-03-18
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
# ## Случайный доступ к элементу ###
def random_access(nums)
# Случайным образом выбрать число из интервала [0, nums.length)
random_index = Random.rand(0...nums.length)
# Получить и вернуть случайный элемент
nums[random_index]
end
# ## Увеличить длину массива ###
# Обратите внимание: Array в Ruby является динамическим массивом и может быть расширен напрямую
# Для удобства обучения эта функция рассматривает Array как массив неизменяемой длины
def extend(nums, enlarge)
# Инициализировать массив увеличенной длины
res = Array.new(nums.length + enlarge, 0)
# Скопировать все элементы исходного массива в новый массив
for i in 0...nums.length
res[i] = nums[i]
end
# Вернуть новый массив после расширения
res
end
# ## Вставка элемента num по индексу index в массив ###
def insert(nums, num, index)
# Сдвинуть элемент с индексом index и все последующие элементы на одну позицию назад
for i in (nums.length - 1).downto(index + 1)
nums[i] = nums[i - 1]
end
# Присвоить num элементу по индексу index
nums[index] = num
end
### Удаление элемента по индексу index ### ### Удаление элемента по индексу index ###
def remove(nums, index) def remove(nums, index)
# Сдвинуть все элементы после индекса index на одну позицию вперед # Сдвинуть все элементы после индекса index на одну позицию вперед
@@ -996,58 +914,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="array.rb" ```ruby title="array.rb"
=begin
File: array.rb
Created Time: 2024-03-18
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
# ## Случайный доступ к элементу ###
def random_access(nums)
# Случайным образом выбрать число из интервала [0, nums.length)
random_index = Random.rand(0...nums.length)
# Получить и вернуть случайный элемент
nums[random_index]
end
# ## Увеличить длину массива ###
# Обратите внимание: Array в Ruby является динамическим массивом и может быть расширен напрямую
# Для удобства обучения эта функция рассматривает Array как массив неизменяемой длины
def extend(nums, enlarge)
# Инициализировать массив увеличенной длины
res = Array.new(nums.length + enlarge, 0)
# Скопировать все элементы исходного массива в новый массив
for i in 0...nums.length
res[i] = nums[i]
end
# Вернуть новый массив после расширения
res
end
# ## Вставка элемента num по индексу index в массив ###
def insert(nums, num, index)
# Сдвинуть элемент с индексом index и все последующие элементы на одну позицию назад
for i in (nums.length - 1).downto(index + 1)
nums[i] = nums[i - 1]
end
# Присвоить num элементу по индексу index
nums[index] = num
end
# ## Удаление элемента по индексу index ###
def remove(nums, index)
# Сдвинуть все элементы после индекса index на одну позицию вперед
for i in index...(nums.length - 1)
nums[i] = nums[i + 1]
end
end
### Обход массива ### ### Обход массива ###
def traverse(nums) def traverse(nums)
count = 0 count = 0
@@ -1236,73 +1102,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="array.rb" ```ruby title="array.rb"
=begin
File: array.rb
Created Time: 2024-03-18
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
# ## Случайный доступ к элементу ###
def random_access(nums)
# Случайным образом выбрать число из интервала [0, nums.length)
random_index = Random.rand(0...nums.length)
# Получить и вернуть случайный элемент
nums[random_index]
end
# ## Увеличить длину массива ###
# Обратите внимание: Array в Ruby является динамическим массивом и может быть расширен напрямую
# Для удобства обучения эта функция рассматривает Array как массив неизменяемой длины
def extend(nums, enlarge)
# Инициализировать массив увеличенной длины
res = Array.new(nums.length + enlarge, 0)
# Скопировать все элементы исходного массива в новый массив
for i in 0...nums.length
res[i] = nums[i]
end
# Вернуть новый массив после расширения
res
end
# ## Вставка элемента num по индексу index в массив ###
def insert(nums, num, index)
# Сдвинуть элемент с индексом index и все последующие элементы на одну позицию назад
for i in (nums.length - 1).downto(index + 1)
nums[i] = nums[i - 1]
end
# Присвоить num элементу по индексу index
nums[index] = num
end
# ## Удаление элемента по индексу index ###
def remove(nums, index)
# Сдвинуть все элементы после индекса index на одну позицию вперед
for i in index...(nums.length - 1)
nums[i] = nums[i + 1]
end
end
# ## Обход массива ###
def traverse(nums)
count = 0
# Обход массива по индексам
for i in 0...nums.length
count += nums[i]
end
# Непосредственно обходить элементы массива
for num in nums
count += num
end
end
### Поиск заданного элемента в массиве ### ### Поиск заданного элемента в массиве ###
def find(nums, target) def find(nums, target)
for i in 0...nums.length for i in 0...nums.length
@@ -1526,22 +1325,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="array.rb" ```ruby title="array.rb"
=begin
File: array.rb
Created Time: 2024-03-18
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
# ## Случайный доступ к элементу ###
def random_access(nums)
# Случайным образом выбрать число из интервала [0, nums.length)
random_index = Random.rand(0...nums.length)
# Получить и вернуть случайный элемент
nums[random_index]
end
### Увеличить длину массива ### ### Увеличить длину массива ###
# Обратите внимание: Array в Ruby является динамическим массивом и может быть расширен напрямую # Обратите внимание: Array в Ruby является динамическим массивом и может быть расширен напрямую
# Для удобства обучения эта функция рассматривает Array как массив неизменяемой длины # Для удобства обучения эта функция рассматривает Array как массив неизменяемой длины
@@ -570,15 +570,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="linked_list.rb" ```ruby title="linked_list.rb"
=begin
File: linked_list.rb
Created Time: 2024-03-18
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
require_relative '../utils/list_node'
require_relative '../utils/print_util'
### Вставка узла _p после узла n0 в связном списке ### ### Вставка узла _p после узла n0 в связном списке ###
# В Ruby `p` — встроенная функция, а `P` — константа, поэтому вместо этого можно использовать `_p` # В Ruby `p` — встроенная функция, а `P` — константа, поэтому вместо этого можно использовать `_p`
def insert(n0, _p) def insert(n0, _p)
@@ -780,23 +771,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="linked_list.rb" ```ruby title="linked_list.rb"
=begin
File: linked_list.rb
Created Time: 2024-03-18
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
require_relative '../utils/list_node'
require_relative '../utils/print_util'
# ## Вставка узла _p после узла n0 в связном списке ###
# В Ruby `p` — встроенная функция, а `P` — константа, поэтому вместо этого можно использовать `_p`
def insert(n0, _p)
n1 = n0.next
_p.next = n1
n0.next = _p
end
### Удаление первого узла после узла n0 в связном списке ### ### Удаление первого узла после узла n0 в связном списке ###
def remove(n0) def remove(n0)
return if n0.next.nil? return if n0.next.nil?
@@ -1001,33 +975,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="linked_list.rb" ```ruby title="linked_list.rb"
=begin
File: linked_list.rb
Created Time: 2024-03-18
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
require_relative '../utils/list_node'
require_relative '../utils/print_util'
# ## Вставка узла _p после узла n0 в связном списке ###
# В Ruby `p` — встроенная функция, а `P` — константа, поэтому вместо этого можно использовать `_p`
def insert(n0, _p)
n1 = n0.next
_p.next = n1
n0.next = _p
end
# ## Удаление первого узла после узла n0 в связном списке ###
def remove(n0)
return if n0.next.nil?
# n0 -> remove_node -> n1
remove_node = n0.next
n1 = remove_node.next
n0.next = n1
end
### Доступ к узлу связного списка по индексу index ### ### Доступ к узлу связного списка по индексу index ###
def access(head, index) def access(head, index)
for i in 0...index for i in 0...index
@@ -1252,43 +1199,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="linked_list.rb" ```ruby title="linked_list.rb"
=begin
File: linked_list.rb
Created Time: 2024-03-18
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
require_relative '../utils/list_node'
require_relative '../utils/print_util'
# ## Вставка узла _p после узла n0 в связном списке ###
# В Ruby `p` — встроенная функция, а `P` — константа, поэтому вместо этого можно использовать `_p`
def insert(n0, _p)
n1 = n0.next
_p.next = n1
n0.next = _p
end
# ## Удаление первого узла после узла n0 в связном списке ###
def remove(n0)
return if n0.next.nil?
# n0 -> remove_node -> n1
remove_node = n0.next
n1 = remove_node.next
n0.next = n1
end
# ## Доступ к узлу связного списка по индексу index ###
def access(head, index)
for i in 0...index
return nil if head.nil?
head = head.next
end
head
end
### Поиск первого узла со значением target в связном списке ### ### Поиск первого узла со значением target в связном списке ###
def find(head, target) def find(head, target)
index = 0 index = 0
@@ -2198,12 +2198,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="my_list.rb" ```ruby title="my_list.rb"
=begin
File: my_list.rb
Created Time: 2024-03-18
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
### Класс списка ### ### Класс списка ###
class MyList class MyList
attr_reader :size # Получить длину списка (текущее число элементов) attr_reader :size # Получить длину списка (текущее число элементов)
@@ -220,15 +220,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="preorder_traversal_i_compact.rb" ```ruby title="preorder_traversal_i_compact.rb"
=begin
File: preorder_traversal_i_compact.rb
Created Time: 2024-05-22
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
require_relative '../utils/tree_node'
require_relative '../utils/print_util'
### Предварительный обход: пример 1 ### ### Предварительный обход: пример 1 ###
def pre_order(root) def pre_order(root)
return unless root return unless root
@@ -534,15 +525,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="preorder_traversal_ii_compact.rb" ```ruby title="preorder_traversal_ii_compact.rb"
=begin
File: preorder_traversal_ii_compact.rb
Created Time: 2024-05-22
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
require_relative '../utils/tree_node'
require_relative '../utils/print_util'
### Предварительный обход: пример 2 ### ### Предварительный обход: пример 2 ###
def pre_order(root) def pre_order(root)
return unless root return unless root
@@ -896,15 +878,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="preorder_traversal_iii_compact.rb" ```ruby title="preorder_traversal_iii_compact.rb"
=begin
File: preorder_traversal_iii_compact.rb
Created Time: 2024-05-22
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
require_relative '../utils/tree_node'
require_relative '../utils/print_util'
### Предварительный обход: пример 3 ### ### Предварительный обход: пример 3 ###
def pre_order(root) def pre_order(root)
# Отсечение # Отсечение
@@ -1906,135 +1879,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="preorder_traversal_iii_template.rb" ```ruby title="preorder_traversal_iii_template.rb"
=begin
File: preorder_traversal_iii_template.rb
Created Time: 2024-05-22
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
require_relative '../utils/tree_node'
require_relative '../utils/print_util'
# ## Проверка, является ли текущее состояние решением ###
def is_solution?(state)
!state.empty? && state.last.val == 7
end
=begin
File: preorder_traversal_iii_template.rb
Created Time: 2024-05-22
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
require_relative '../utils/tree_node'
require_relative '../utils/print_util'
# ## Проверка, является ли текущее состояние решением ###
def is_solution?(state)
!state.empty? && state.last.val == 7
end
# ## Записать решение ###
def record_solution(state, res)
res << state.dup
end
=begin
File: preorder_traversal_iii_template.rb
Created Time: 2024-05-22
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
require_relative '../utils/tree_node'
require_relative '../utils/print_util'
# ## Проверка, является ли текущее состояние решением ###
def is_solution?(state)
!state.empty? && state.last.val == 7
end
# ## Записать решение ###
def record_solution(state, res)
res << state.dup
end
# ## Проверка допустимости этого выбора в текущем состоянии ###
def is_valid?(state, choice)
choice && choice.val != 3
end
=begin
File: preorder_traversal_iii_template.rb
Created Time: 2024-05-22
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
require_relative '../utils/tree_node'
require_relative '../utils/print_util'
# ## Проверка, является ли текущее состояние решением ###
def is_solution?(state)
!state.empty? && state.last.val == 7
end
# ## Записать решение ###
def record_solution(state, res)
res << state.dup
end
# ## Проверка допустимости этого выбора в текущем состоянии ###
def is_valid?(state, choice)
choice && choice.val != 3
end
# ## Обновить состояние ###
def make_choice(state, choice)
state << choice
end
=begin
File: preorder_traversal_iii_template.rb
Created Time: 2024-05-22
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
require_relative '../utils/tree_node'
require_relative '../utils/print_util'
# ## Проверка, является ли текущее состояние решением ###
def is_solution?(state)
!state.empty? && state.last.val == 7
end
# ## Записать решение ###
def record_solution(state, res)
res << state.dup
end
# ## Проверка допустимости этого выбора в текущем состоянии ###
def is_valid?(state, choice)
choice && choice.val != 3
end
# ## Обновить состояние ###
def make_choice(state, choice)
state << choice
end
# ## Восстановить состояние ###
def undo_choice(state, choice)
state.pop
end
=begin
File: preorder_traversal_iii_template.rb
Created Time: 2024-05-22
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
require_relative '../utils/tree_node'
require_relative '../utils/print_util'
### Проверка, является ли текущее состояние решением ### ### Проверка, является ли текущее состояние решением ###
def is_solution?(state) def is_solution?(state)
!state.empty? && state.last.val == 7 !state.empty? && state.last.val == 7
@@ -703,45 +703,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="n_queens.rb" ```ruby title="n_queens.rb"
=begin
File: n_queens.rb
Created Time: 2024-05-21
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
# ## Алгоритм бэктрекинга: n ферзей ###
def backtrack(row, n, state, res, cols, diags1, diags2)
# Когда все строки уже обработаны, записать решение
if row == n
res << state.map { |row| row.dup }
return
end
# Обойти все столбцы
for col in 0...n
# Вычислить главную и побочную диагонали, соответствующие этой клетке
diag1 = row - col + n - 1
diag2 = row + col
# Отсечение: в столбце, главной диагонали и побочной диагонали этой клетки не должно быть ферзей
if !cols[col] && !diags1[diag1] && !diags2[diag2]
# Попытка: поставить ферзя в эту клетку
state[row][col] = "Q"
cols[col] = diags1[diag1] = diags2[diag2] = true
# Перейти к размещению следующей строки
backtrack(row + 1, n, state, res, cols, diags1, diags2)
# Откат: восстановить эту клетку как пустую
state[row][col] = "#"
cols[col] = diags1[diag1] = diags2[diag2] = false
end
end
end
=begin
File: n_queens.rb
Created Time: 2024-05-21
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
### Алгоритм бэктрекинга: n ферзей ### ### Алгоритм бэктрекинга: n ферзей ###
def backtrack(row, n, state, res, cols, diags1, diags2) def backtrack(row, n, state, res, cols, diags1, diags2)
# Когда все строки уже обработаны, записать решение # Когда все строки уже обработаны, записать решение
@@ -506,42 +506,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="permutations_i.rb" ```ruby title="permutations_i.rb"
=begin
File: permutations_i.rb
Created Time: 2024-05-22
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
# ## Алгоритм бэктрекинга: все перестановки I ###
def backtrack(state, choices, selected, res)
# Когда длина состояния равна числу элементов, записать решение
if state.length == choices.length
res << state.dup
return
end
# Перебор всех вариантов выбора
choices.each_with_index do |choice, i|
# Отсечение: нельзя выбирать один и тот же элемент повторно
unless selected[i]
# Попытка: сделать выбор и обновить состояние
selected[i] = true
state << choice
# Перейти к следующему выбору
backtrack(state, choices, selected, res)
# Откат: отменить выбор и восстановить предыдущее состояние
selected[i] = false
state.pop
end
end
end
=begin
File: permutations_i.rb
Created Time: 2024-05-22
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
### Алгоритм бэктрекинга: все перестановки I ### ### Алгоритм бэктрекинга: все перестановки I ###
def backtrack(state, choices, selected, res) def backtrack(state, choices, selected, res)
# Когда длина состояния равна числу элементов, записать решение # Когда длина состояния равна числу элементов, записать решение
@@ -1087,44 +1051,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="permutations_ii.rb" ```ruby title="permutations_ii.rb"
=begin
File: permutations_ii.rb
Created Time: 2024-05-22
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
# ## Алгоритм бэктрекинга: все перестановки II ###
def backtrack(state, choices, selected, res)
# Когда длина состояния равна числу элементов, записать решение
if state.length == choices.length
res << state.dup
return
end
# Перебор всех вариантов выбора
duplicated = Set.new
choices.each_with_index do |choice, i|
# Отсечение: нельзя выбирать один и тот же элемент повторно и нельзя повторно выбирать равные элементы
if !selected[i] && !duplicated.include?(choice)
# Попытка: сделать выбор и обновить состояние
duplicated.add(choice)
selected[i] = true
state << choice
# Перейти к следующему выбору
backtrack(state, choices, selected, res)
# Откат: отменить выбор и восстановить предыдущее состояние
selected[i] = false
state.pop
end
end
end
=begin
File: permutations_ii.rb
Created Time: 2024-05-22
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
### Алгоритм бэктрекинга: все перестановки II ### ### Алгоритм бэктрекинга: все перестановки II ###
def backtrack(state, choices, selected, res) def backtrack(state, choices, selected, res)
# Когда длина состояния равна числу элементов, записать решение # Когда длина состояния равна числу элементов, записать решение
@@ -470,39 +470,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="subset_sum_i_naive.rb" ```ruby title="subset_sum_i_naive.rb"
=begin
File: subset_sum_i_naive.rb
Created Time: 2024-05-22
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
# ## Алгоритм бэктрекинга: сумма подмножеств I ###
def backtrack(state, target, total, choices, res)
# Если сумма подмножества равна target, записать решение
if total == target
res << state.dup
return
end
# Перебор всех вариантов выбора
for i in 0...choices.length
# Отсечение: если сумма подмножества превышает target, пропустить этот выбор
next if total + choices[i] > target
# Попытка: сделать выбор и обновить элемент и total
state << choices[i]
# Перейти к следующему выбору
backtrack(state, target, total + choices[i], choices, res)
# Откат: отменить выбор и восстановить предыдущее состояние
state.pop
end
end
=begin
File: subset_sum_i_naive.rb
Created Time: 2024-05-22
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
### Алгоритм бэктрекинга: сумма подмножеств I ### ### Алгоритм бэктрекинга: сумма подмножеств I ###
def backtrack(state, target, total, choices, res) def backtrack(state, target, total, choices, res)
# Если сумма подмножества равна target, записать решение # Если сумма подмножества равна target, записать решение
@@ -1062,40 +1029,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="subset_sum_i.rb" ```ruby title="subset_sum_i.rb"
=begin
File: subset_sum_i.rb
Created Time: 2024-05-22
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
# ## Алгоритм бэктрекинга: сумма подмножеств I ###
def backtrack(state, target, choices, start, res)
# Если сумма подмножества равна target, записать решение
if target.zero?
res << state.dup
return
end
# Обойти все варианты выбора
# Отсечение 2: начинать обход с start, чтобы избежать генерации повторяющихся подмножеств
for i in start...choices.length
# Отсечение 1: если сумма подмножества превышает target, немедленно завершить цикл
# Это связано с тем, что массив уже отсортирован, следующие элементы больше, и сумма подмножества точно превысит target
break if target - choices[i] < 0
# Попытка: сделать выбор и обновить target и start
state << choices[i]
# Перейти к следующему выбору
backtrack(state, target - choices[i], choices, i, res)
# Откат: отменить выбор и восстановить предыдущее состояние
state.pop
end
end
=begin
File: subset_sum_i.rb
Created Time: 2024-05-22
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
### Алгоритм бэктрекинга: сумма подмножеств I ### ### Алгоритм бэктрекинга: сумма подмножеств I ###
def backtrack(state, target, choices, start, res) def backtrack(state, target, choices, start, res)
# Если сумма подмножества равна target, записать решение # Если сумма подмножества равна target, записать решение
@@ -1703,44 +1636,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="subset_sum_ii.rb" ```ruby title="subset_sum_ii.rb"
=begin
File: subset_sum_ii.rb
Created Time: 2024-05-22
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
# ## Алгоритм бэктрекинга: сумма подмножеств II ###
def backtrack(state, target, choices, start, res)
# Если сумма подмножества равна target, записать решение
if target.zero?
res << state.dup
return
end
# Обойти все варианты выбора
# Отсечение 2: начинать обход с start, чтобы избежать генерации повторяющихся подмножеств
# Отсечение 3: начинать обход с start, чтобы избежать повторного выбора одного и того же элемента
for i in start...choices.length
# Отсечение 1: если сумма подмножества превышает target, немедленно завершить цикл
# Это связано с тем, что массив уже отсортирован, следующие элементы больше, и сумма подмножества точно превысит target
break if target - choices[i] < 0
# Отсечение 4: если этот элемент равен элементу слева, значит ветвь поиска повторяется, ее нужно сразу пропустить
next if i > start && choices[i] == choices[i - 1]
# Попытка: сделать выбор и обновить target и start
state << choices[i]
# Перейти к следующему выбору
backtrack(state, target - choices[i], choices, i + 1, res)
# Откат: отменить выбор и восстановить предыдущее состояние
state.pop
end
end
=begin
File: subset_sum_ii.rb
Created Time: 2024-05-22
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
### Алгоритм бэктрекинга: сумма подмножеств II ### ### Алгоритм бэктрекинга: сумма подмножеств II ###
def backtrack(state, target, choices, start, res) def backtrack(state, target, choices, start, res)
# Если сумма подмножества равна target, записать решение # Если сумма подмножества равна target, записать решение
@@ -185,12 +185,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="iteration.rb" ```ruby title="iteration.rb"
=begin
File: iteration.rb
Created Time: 2024-03-30
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com), Cy (9738314@gmail.com)
=end
### Цикл for ### ### Цикл for ###
def for_loop(n) def for_loop(n)
res = 0 res = 0
@@ -419,24 +413,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="iteration.rb" ```ruby title="iteration.rb"
=begin
File: iteration.rb
Created Time: 2024-03-30
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com), Cy (9738314@gmail.com)
=end
# ## Цикл for ###
def for_loop(n)
res = 0
# Циклическое суммирование 1, 2, ..., n-1, n
for i in 1..n
res += i
end
res
end
### Цикл while ### ### Цикл while ###
def while_loop(n) def while_loop(n)
res = 0 res = 0
@@ -680,38 +656,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="iteration.rb" ```ruby title="iteration.rb"
=begin
File: iteration.rb
Created Time: 2024-03-30
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com), Cy (9738314@gmail.com)
=end
# ## Цикл for ###
def for_loop(n)
res = 0
# Циклическое суммирование 1, 2, ..., n-1, n
for i in 1..n
res += i
end
res
end
# ## Цикл while ###
def while_loop(n)
res = 0
i = 1 # Инициализация условной переменной
# Циклическое суммирование 1, 2, ..., n-1, n
while i <= n
res += i
i += 1 # Обновить условную переменную
end
res
end
### Цикл while (двойное обновление) ### ### Цикл while (двойное обновление) ###
def while_loop_ii(n) def while_loop_ii(n)
res = 0 res = 0
@@ -948,54 +892,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="iteration.rb" ```ruby title="iteration.rb"
=begin
File: iteration.rb
Created Time: 2024-03-30
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com), Cy (9738314@gmail.com)
=end
# ## Цикл for ###
def for_loop(n)
res = 0
# Циклическое суммирование 1, 2, ..., n-1, n
for i in 1..n
res += i
end
res
end
# ## Цикл while ###
def while_loop(n)
res = 0
i = 1 # Инициализация условной переменной
# Циклическое суммирование 1, 2, ..., n-1, n
while i <= n
res += i
i += 1 # Обновить условную переменную
end
res
end
# ## Цикл while (двойное обновление) ###
def while_loop_ii(n)
res = 0
i = 1 # Инициализация условной переменной
# Циклическое суммирование 1, 4, 10, ...
while i <= n
res += i
# Обновить условную переменную
i += 1
i *= 2
end
res
end
### Двойной цикл for ### ### Двойной цикл for ###
def nested_for_loop(n) def nested_for_loop(n)
res = "" res = ""
@@ -1224,12 +1120,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="recursion.rb" ```ruby title="recursion.rb"
=begin
File: recursion.rb
Created Time: 2024-03-30
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
### Рекурсия ### ### Рекурсия ###
def recur(n) def recur(n)
# Условие завершения # Условие завершения
@@ -1445,42 +1335,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="recursion.rb" ```ruby title="recursion.rb"
=begin
File: recursion.rb
Created Time: 2024-03-30
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
# ## Рекурсия ###
def recur(n)
# Условие завершения
return 1 if n == 1
# Рекурсия: рекурсивный вызов
res = recur(n - 1)
# Возврат: вернуть результат
n + res
end
# ## Имитация рекурсии итерацией ###
def for_loop_recur(n)
# Использовать явный стек для имитации системного стека вызовов
stack = []
res = 0
# Рекурсия: рекурсивный вызов
for i in n.downto(0)
# Имитировать «рекурсию» с помощью операции помещения в стек
stack << i
end
# Возврат: вернуть результат
while !stack.empty?
res += stack.pop
end
# res = 1+2+3+...+n
res
end
### Хвостовая рекурсия ### ### Хвостовая рекурсия ###
def tail_recur(n, res) def tail_recur(n, res)
# Условие завершения # Условие завершения
@@ -1705,50 +1559,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="recursion.rb" ```ruby title="recursion.rb"
=begin
File: recursion.rb
Created Time: 2024-03-30
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
# ## Рекурсия ###
def recur(n)
# Условие завершения
return 1 if n == 1
# Рекурсия: рекурсивный вызов
res = recur(n - 1)
# Возврат: вернуть результат
n + res
end
# ## Имитация рекурсии итерацией ###
def for_loop_recur(n)
# Использовать явный стек для имитации системного стека вызовов
stack = []
res = 0
# Рекурсия: рекурсивный вызов
for i in n.downto(0)
# Имитировать «рекурсию» с помощью операции помещения в стек
stack << i
end
# Возврат: вернуть результат
while !stack.empty?
res += stack.pop
end
# res = 1+2+3+...+n
res
end
# ## Хвостовая рекурсия ###
def tail_recur(n, res)
# Условие завершения
return res if n == 0
# Хвостовой рекурсивный вызов
tail_recur(n - 1, res + n)
end
### Последовательность Фибоначчи: рекурсия ### ### Последовательность Фибоначчи: рекурсия ###
def fib(n) def fib(n)
# Условие завершения: f(1) = 0, f(2) = 1 # Условие завершения: f(1) = 0, f(2) = 1
@@ -2084,22 +1894,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="recursion.rb" ```ruby title="recursion.rb"
=begin
File: recursion.rb
Created Time: 2024-03-30
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
# ## Рекурсия ###
def recur(n)
# Условие завершения
return 1 if n == 1
# Рекурсия: рекурсивный вызов
res = recur(n - 1)
# Возврат: вернуть результат
n + res
end
### Имитация рекурсии итерацией ### ### Имитация рекурсии итерацией ###
def for_loop_recur(n) def for_loop_recur(n)
# Использовать явный стек для имитации системного стека вызовов # Использовать явный стек для имитации системного стека вызовов
@@ -1157,32 +1157,6 @@ $$
=== "Ruby" === "Ruby"
```ruby title="space_complexity.rb" ```ruby title="space_complexity.rb"
=begin
File: space_complexity.rb
Created Time: 2024-03-30
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
require_relative '../utils/list_node'
require_relative '../utils/tree_node'
require_relative '../utils/print_util'
# ## Функция ###
def function
# Выполнить некоторые операции
0
end
=begin
File: space_complexity.rb
Created Time: 2024-03-30
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
require_relative '../utils/list_node'
require_relative '../utils/tree_node'
require_relative '../utils/print_util'
### Функция ### ### Функция ###
def function def function
# Выполнить некоторые операции # Выполнить некоторые операции
@@ -1468,35 +1442,6 @@ $$
=== "Ruby" === "Ruby"
```ruby title="space_complexity.rb" ```ruby title="space_complexity.rb"
=begin
File: space_complexity.rb
Created Time: 2024-03-30
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
require_relative '../utils/list_node'
require_relative '../utils/tree_node'
require_relative '../utils/print_util'
# ## Функция ###
def function
# Выполнить некоторые операции
0
end
# ## Постоянная сложность ###
def constant(n)
# Константы, переменные и объекты занимают O(1) памяти
a = 0
nums = [0] * 10000
node = ListNode.new
# Переменные в цикле занимают O(1) памяти
(0...n).each { c = 0 }
# Функции в цикле занимают O(1) памяти
(0...n).each { function }
end
### Линейная сложность ### ### Линейная сложность ###
def linear(n) def linear(n)
# Список длины n занимает O(n) памяти # Список длины n занимает O(n) памяти
@@ -1662,47 +1607,6 @@ $$
=== "Ruby" === "Ruby"
```ruby title="space_complexity.rb" ```ruby title="space_complexity.rb"
=begin
File: space_complexity.rb
Created Time: 2024-03-30
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
require_relative '../utils/list_node'
require_relative '../utils/tree_node'
require_relative '../utils/print_util'
# ## Функция ###
def function
# Выполнить некоторые операции
0
end
# ## Постоянная сложность ###
def constant(n)
# Константы, переменные и объекты занимают O(1) памяти
a = 0
nums = [0] * 10000
node = ListNode.new
# Переменные в цикле занимают O(1) памяти
(0...n).each { c = 0 }
# Функции в цикле занимают O(1) памяти
(0...n).each { function }
end
# ## Линейная сложность ###
def linear(n)
# Список длины n занимает O(n) памяти
nums = Array.new(n, 0)
# Хеш-таблица длины n занимает O(n) памяти
hmap = {}
for i in 0...n
hmap[i] = i.to_s
end
end
### Линейная сложность (рекурсивная реализация) ### ### Линейная сложность (рекурсивная реализация) ###
def linear_recur(n) def linear_recur(n)
puts "Рекурсия n = #{n}" puts "Рекурсия n = #{n}"
@@ -1937,54 +1841,6 @@ $$
=== "Ruby" === "Ruby"
```ruby title="space_complexity.rb" ```ruby title="space_complexity.rb"
=begin
File: space_complexity.rb
Created Time: 2024-03-30
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
require_relative '../utils/list_node'
require_relative '../utils/tree_node'
require_relative '../utils/print_util'
# ## Функция ###
def function
# Выполнить некоторые операции
0
end
# ## Постоянная сложность ###
def constant(n)
# Константы, переменные и объекты занимают O(1) памяти
a = 0
nums = [0] * 10000
node = ListNode.new
# Переменные в цикле занимают O(1) памяти
(0...n).each { c = 0 }
# Функции в цикле занимают O(1) памяти
(0...n).each { function }
end
# ## Линейная сложность ###
def linear(n)
# Список длины n занимает O(n) памяти
nums = Array.new(n, 0)
# Хеш-таблица длины n занимает O(n) памяти
hmap = {}
for i in 0...n
hmap[i] = i.to_s
end
end
# ## Линейная сложность (рекурсивная реализация) ###
def linear_recur(n)
puts "Рекурсия n = #{n}"
return if n == 1
linear_recur(n - 1)
end
### Квадратичная сложность ### ### Квадратичная сложность ###
def quadratic(n) def quadratic(n)
# Двумерный список занимает O(n^2) памяти # Двумерный список занимает O(n^2) памяти
@@ -2163,60 +2019,6 @@ $$
=== "Ruby" === "Ruby"
```ruby title="space_complexity.rb" ```ruby title="space_complexity.rb"
=begin
File: space_complexity.rb
Created Time: 2024-03-30
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
require_relative '../utils/list_node'
require_relative '../utils/tree_node'
require_relative '../utils/print_util'
# ## Функция ###
def function
# Выполнить некоторые операции
0
end
# ## Постоянная сложность ###
def constant(n)
# Константы, переменные и объекты занимают O(1) памяти
a = 0
nums = [0] * 10000
node = ListNode.new
# Переменные в цикле занимают O(1) памяти
(0...n).each { c = 0 }
# Функции в цикле занимают O(1) памяти
(0...n).each { function }
end
# ## Линейная сложность ###
def linear(n)
# Список длины n занимает O(n) памяти
nums = Array.new(n, 0)
# Хеш-таблица длины n занимает O(n) памяти
hmap = {}
for i in 0...n
hmap[i] = i.to_s
end
end
# ## Линейная сложность (рекурсивная реализация) ###
def linear_recur(n)
puts "Рекурсия n = #{n}"
return if n == 1
linear_recur(n - 1)
end
# ## Квадратичная сложность ###
def quadratic(n)
# Двумерный список занимает O(n^2) памяти
Array.new(n) { Array.new(n, 0) }
end
### Квадратичная сложность (рекурсивная реализация) ### ### Квадратичная сложность (рекурсивная реализация) ###
def quadratic_recur(n) def quadratic_recur(n)
return 0 unless n > 0 return 0 unless n > 0
@@ -2410,69 +2212,6 @@ $$
=== "Ruby" === "Ruby"
```ruby title="space_complexity.rb" ```ruby title="space_complexity.rb"
=begin
File: space_complexity.rb
Created Time: 2024-03-30
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
require_relative '../utils/list_node'
require_relative '../utils/tree_node'
require_relative '../utils/print_util'
# ## Функция ###
def function
# Выполнить некоторые операции
0
end
# ## Постоянная сложность ###
def constant(n)
# Константы, переменные и объекты занимают O(1) памяти
a = 0
nums = [0] * 10000
node = ListNode.new
# Переменные в цикле занимают O(1) памяти
(0...n).each { c = 0 }
# Функции в цикле занимают O(1) памяти
(0...n).each { function }
end
# ## Линейная сложность ###
def linear(n)
# Список длины n занимает O(n) памяти
nums = Array.new(n, 0)
# Хеш-таблица длины n занимает O(n) памяти
hmap = {}
for i in 0...n
hmap[i] = i.to_s
end
end
# ## Линейная сложность (рекурсивная реализация) ###
def linear_recur(n)
puts "Рекурсия n = #{n}"
return if n == 1
linear_recur(n - 1)
end
# ## Квадратичная сложность ###
def quadratic(n)
# Двумерный список занимает O(n^2) памяти
Array.new(n) { Array.new(n, 0) }
end
# ## Квадратичная сложность (рекурсивная реализация) ###
def quadratic_recur(n)
return 0 unless n > 0
# Длина массива nums равна n, n-1, ..., 2, 1
nums = Array.new(n, 0)
quadratic_recur(n - 1)
end
### Экспоненциальная сложность (построение полного двоичного дерева) ### ### Экспоненциальная сложность (построение полного двоичного дерева) ###
def build_tree(n) def build_tree(n)
return if n == 0 return if n == 0
@@ -1182,12 +1182,6 @@ $$
=== "Ruby" === "Ruby"
```ruby title="time_complexity.rb" ```ruby title="time_complexity.rb"
=begin
File: time_complexity.rb
Created Time: 2024-03-30
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
### Постоянная сложность ### ### Постоянная сложность ###
def constant(n) def constant(n)
count = 0 count = 0
@@ -1357,22 +1351,6 @@ $$
=== "Ruby" === "Ruby"
```ruby title="time_complexity.rb" ```ruby title="time_complexity.rb"
=begin
File: time_complexity.rb
Created Time: 2024-03-30
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
# ## Постоянная сложность ###
def constant(n)
count = 0
size = 100000
(0...size).each { count += 1 }
count
end
### Линейная сложность ### ### Линейная сложность ###
def linear(n) def linear(n)
count = 0 count = 0
@@ -1557,29 +1535,6 @@ $$
=== "Ruby" === "Ruby"
```ruby title="time_complexity.rb" ```ruby title="time_complexity.rb"
=begin
File: time_complexity.rb
Created Time: 2024-03-30
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
# ## Постоянная сложность ###
def constant(n)
count = 0
size = 100000
(0...size).each { count += 1 }
count
end
# ## Линейная сложность ###
def linear(n)
count = 0
(0...n).each { count += 1 }
count
end
### Линейная сложность (обход массива) ### ### Линейная сложность (обход массива) ###
def array_traversal(nums) def array_traversal(nums)
count = 0 count = 0
@@ -1796,41 +1751,6 @@ $$
=== "Ruby" === "Ruby"
```ruby title="time_complexity.rb" ```ruby title="time_complexity.rb"
=begin
File: time_complexity.rb
Created Time: 2024-03-30
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
# ## Постоянная сложность ###
def constant(n)
count = 0
size = 100000
(0...size).each { count += 1 }
count
end
# ## Линейная сложность ###
def linear(n)
count = 0
(0...n).each { count += 1 }
count
end
# ## Линейная сложность (обход массива) ###
def array_traversal(nums)
count = 0
# Число итераций пропорционально длине массива
for num in nums
count += 1
end
count
end
### Квадратичная сложность ### ### Квадратичная сложность ###
def quadratic(n) def quadratic(n)
count = 0 count = 0
@@ -2133,55 +2053,6 @@ $$
=== "Ruby" === "Ruby"
```ruby title="time_complexity.rb" ```ruby title="time_complexity.rb"
=begin
File: time_complexity.rb
Created Time: 2024-03-30
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
# ## Постоянная сложность ###
def constant(n)
count = 0
size = 100000
(0...size).each { count += 1 }
count
end
# ## Линейная сложность ###
def linear(n)
count = 0
(0...n).each { count += 1 }
count
end
# ## Линейная сложность (обход массива) ###
def array_traversal(nums)
count = 0
# Число итераций пропорционально длине массива
for num in nums
count += 1
end
count
end
# ## Квадратичная сложность ###
def quadratic(n)
count = 0
# Число итераций квадратично зависит от размера данных n
for i in 0...n
for j in 0...n
count += 1
end
end
count
end
### Квадратичная сложность (пузырьковая сортировка) ### ### Квадратичная сложность (пузырьковая сортировка) ###
def bubble_sort(nums) def bubble_sort(nums)
count = 0 # Счетчик count = 0 # Счетчик
@@ -2438,76 +2309,6 @@ $$
=== "Ruby" === "Ruby"
```ruby title="time_complexity.rb" ```ruby title="time_complexity.rb"
=begin
File: time_complexity.rb
Created Time: 2024-03-30
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
# ## Постоянная сложность ###
def constant(n)
count = 0
size = 100000
(0...size).each { count += 1 }
count
end
# ## Линейная сложность ###
def linear(n)
count = 0
(0...n).each { count += 1 }
count
end
# ## Линейная сложность (обход массива) ###
def array_traversal(nums)
count = 0
# Число итераций пропорционально длине массива
for num in nums
count += 1
end
count
end
# ## Квадратичная сложность ###
def quadratic(n)
count = 0
# Число итераций квадратично зависит от размера данных n
for i in 0...n
for j in 0...n
count += 1
end
end
count
end
# ## Квадратичная сложность (пузырьковая сортировка) ###
def bubble_sort(nums)
count = 0 # Счетчик
# Внешний цикл: неотсортированный диапазон [0, i]
for i in (nums.length - 1).downto(0)
# Внутренний цикл: переместить максимальный элемент неотсортированного диапазона [0, i] в его правый конец
for j in 0...i
if nums[j] > nums[j + 1]
# Поменять местами nums[j] и nums[j + 1]
tmp = nums[j]
nums[j] = nums[j + 1]
nums[j + 1] = tmp
count += 3 # Обмен элементов включает 3 элементарные операции
end
end
end
count
end
### Экспоненциальная сложность (итеративная реализация) ### ### Экспоненциальная сложность (итеративная реализация) ###
def exponential(n) def exponential(n)
count, base = 0, 1 count, base = 0, 1
@@ -2668,90 +2469,6 @@ $$
=== "Ruby" === "Ruby"
```ruby title="time_complexity.rb" ```ruby title="time_complexity.rb"
=begin
File: time_complexity.rb
Created Time: 2024-03-30
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
# ## Постоянная сложность ###
def constant(n)
count = 0
size = 100000
(0...size).each { count += 1 }
count
end
# ## Линейная сложность ###
def linear(n)
count = 0
(0...n).each { count += 1 }
count
end
# ## Линейная сложность (обход массива) ###
def array_traversal(nums)
count = 0
# Число итераций пропорционально длине массива
for num in nums
count += 1
end
count
end
# ## Квадратичная сложность ###
def quadratic(n)
count = 0
# Число итераций квадратично зависит от размера данных n
for i in 0...n
for j in 0...n
count += 1
end
end
count
end
# ## Квадратичная сложность (пузырьковая сортировка) ###
def bubble_sort(nums)
count = 0 # Счетчик
# Внешний цикл: неотсортированный диапазон [0, i]
for i in (nums.length - 1).downto(0)
# Внутренний цикл: переместить максимальный элемент неотсортированного диапазона [0, i] в его правый конец
for j in 0...i
if nums[j] > nums[j + 1]
# Поменять местами nums[j] и nums[j + 1]
tmp = nums[j]
nums[j] = nums[j + 1]
nums[j + 1] = tmp
count += 3 # Обмен элементов включает 3 элементарные операции
end
end
end
count
end
# ## Экспоненциальная сложность (итеративная реализация) ###
def exponential(n)
count, base = 0, 1
# На каждом шаге клетка делится надвое, образуя последовательность 1, 2, 4, 8, ..., 2^(n-1)
(0...n).each do
(0...base).each { count += 1 }
base *= 2
end
# count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1
count
end
### Экспоненциальная сложность (рекурсивная реализация) ### ### Экспоненциальная сложность (рекурсивная реализация) ###
def exp_recur(n) def exp_recur(n)
return 1 if n == 1 return 1 if n == 1
@@ -2943,96 +2660,6 @@ $$
=== "Ruby" === "Ruby"
```ruby title="time_complexity.rb" ```ruby title="time_complexity.rb"
=begin
File: time_complexity.rb
Created Time: 2024-03-30
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
# ## Постоянная сложность ###
def constant(n)
count = 0
size = 100000
(0...size).each { count += 1 }
count
end
# ## Линейная сложность ###
def linear(n)
count = 0
(0...n).each { count += 1 }
count
end
# ## Линейная сложность (обход массива) ###
def array_traversal(nums)
count = 0
# Число итераций пропорционально длине массива
for num in nums
count += 1
end
count
end
# ## Квадратичная сложность ###
def quadratic(n)
count = 0
# Число итераций квадратично зависит от размера данных n
for i in 0...n
for j in 0...n
count += 1
end
end
count
end
# ## Квадратичная сложность (пузырьковая сортировка) ###
def bubble_sort(nums)
count = 0 # Счетчик
# Внешний цикл: неотсортированный диапазон [0, i]
for i in (nums.length - 1).downto(0)
# Внутренний цикл: переместить максимальный элемент неотсортированного диапазона [0, i] в его правый конец
for j in 0...i
if nums[j] > nums[j + 1]
# Поменять местами nums[j] и nums[j + 1]
tmp = nums[j]
nums[j] = nums[j + 1]
nums[j + 1] = tmp
count += 3 # Обмен элементов включает 3 элементарные операции
end
end
end
count
end
# ## Экспоненциальная сложность (итеративная реализация) ###
def exponential(n)
count, base = 0, 1
# На каждом шаге клетка делится надвое, образуя последовательность 1, 2, 4, 8, ..., 2^(n-1)
(0...n).each do
(0...base).each { count += 1 }
base *= 2
end
# count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1
count
end
# ## Экспоненциальная сложность (рекурсивная реализация) ###
def exp_recur(n)
return 1 if n == 1
exp_recur(n - 1) + exp_recur(n - 1) + 1
end
### Логарифмическая сложность (итеративная реализация) ### ### Логарифмическая сложность (итеративная реализация) ###
def logarithmic(n) def logarithmic(n)
count = 0 count = 0
@@ -3190,108 +2817,6 @@ $$
=== "Ruby" === "Ruby"
```ruby title="time_complexity.rb" ```ruby title="time_complexity.rb"
=begin
File: time_complexity.rb
Created Time: 2024-03-30
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
# ## Постоянная сложность ###
def constant(n)
count = 0
size = 100000
(0...size).each { count += 1 }
count
end
# ## Линейная сложность ###
def linear(n)
count = 0
(0...n).each { count += 1 }
count
end
# ## Линейная сложность (обход массива) ###
def array_traversal(nums)
count = 0
# Число итераций пропорционально длине массива
for num in nums
count += 1
end
count
end
# ## Квадратичная сложность ###
def quadratic(n)
count = 0
# Число итераций квадратично зависит от размера данных n
for i in 0...n
for j in 0...n
count += 1
end
end
count
end
# ## Квадратичная сложность (пузырьковая сортировка) ###
def bubble_sort(nums)
count = 0 # Счетчик
# Внешний цикл: неотсортированный диапазон [0, i]
for i in (nums.length - 1).downto(0)
# Внутренний цикл: переместить максимальный элемент неотсортированного диапазона [0, i] в его правый конец
for j in 0...i
if nums[j] > nums[j + 1]
# Поменять местами nums[j] и nums[j + 1]
tmp = nums[j]
nums[j] = nums[j + 1]
nums[j + 1] = tmp
count += 3 # Обмен элементов включает 3 элементарные операции
end
end
end
count
end
# ## Экспоненциальная сложность (итеративная реализация) ###
def exponential(n)
count, base = 0, 1
# На каждом шаге клетка делится надвое, образуя последовательность 1, 2, 4, 8, ..., 2^(n-1)
(0...n).each do
(0...base).each { count += 1 }
base *= 2
end
# count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1
count
end
# ## Экспоненциальная сложность (рекурсивная реализация) ###
def exp_recur(n)
return 1 if n == 1
exp_recur(n - 1) + exp_recur(n - 1) + 1
end
# ## Логарифмическая сложность (итеративная реализация) ###
def logarithmic(n)
count = 0
while n > 1
n /= 2
count += 1
end
count
end
### Логарифмическая сложность (рекурсивная реализация) ### ### Логарифмическая сложность (рекурсивная реализация) ###
def log_recur(n) def log_recur(n)
return 0 unless n > 1 return 0 unless n > 1
@@ -3502,114 +3027,6 @@ $$
=== "Ruby" === "Ruby"
```ruby title="time_complexity.rb" ```ruby title="time_complexity.rb"
=begin
File: time_complexity.rb
Created Time: 2024-03-30
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
# ## Постоянная сложность ###
def constant(n)
count = 0
size = 100000
(0...size).each { count += 1 }
count
end
# ## Линейная сложность ###
def linear(n)
count = 0
(0...n).each { count += 1 }
count
end
# ## Линейная сложность (обход массива) ###
def array_traversal(nums)
count = 0
# Число итераций пропорционально длине массива
for num in nums
count += 1
end
count
end
# ## Квадратичная сложность ###
def quadratic(n)
count = 0
# Число итераций квадратично зависит от размера данных n
for i in 0...n
for j in 0...n
count += 1
end
end
count
end
# ## Квадратичная сложность (пузырьковая сортировка) ###
def bubble_sort(nums)
count = 0 # Счетчик
# Внешний цикл: неотсортированный диапазон [0, i]
for i in (nums.length - 1).downto(0)
# Внутренний цикл: переместить максимальный элемент неотсортированного диапазона [0, i] в его правый конец
for j in 0...i
if nums[j] > nums[j + 1]
# Поменять местами nums[j] и nums[j + 1]
tmp = nums[j]
nums[j] = nums[j + 1]
nums[j + 1] = tmp
count += 3 # Обмен элементов включает 3 элементарные операции
end
end
end
count
end
# ## Экспоненциальная сложность (итеративная реализация) ###
def exponential(n)
count, base = 0, 1
# На каждом шаге клетка делится надвое, образуя последовательность 1, 2, 4, 8, ..., 2^(n-1)
(0...n).each do
(0...base).each { count += 1 }
base *= 2
end
# count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1
count
end
# ## Экспоненциальная сложность (рекурсивная реализация) ###
def exp_recur(n)
return 1 if n == 1
exp_recur(n - 1) + exp_recur(n - 1) + 1
end
# ## Логарифмическая сложность (итеративная реализация) ###
def logarithmic(n)
count = 0
while n > 1
n /= 2
count += 1
end
count
end
# ## Логарифмическая сложность (рекурсивная реализация) ###
def log_recur(n)
return 0 unless n > 1
log_recur(n / 2) + 1
end
### Линейно-логарифмическая сложность ### ### Линейно-логарифмическая сложность ###
def linear_log_recur(n) def linear_log_recur(n)
return 1 unless n > 1 return 1 unless n > 1
@@ -3835,124 +3252,6 @@ $$
=== "Ruby" === "Ruby"
```ruby title="time_complexity.rb" ```ruby title="time_complexity.rb"
=begin
File: time_complexity.rb
Created Time: 2024-03-30
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
# ## Постоянная сложность ###
def constant(n)
count = 0
size = 100000
(0...size).each { count += 1 }
count
end
# ## Линейная сложность ###
def linear(n)
count = 0
(0...n).each { count += 1 }
count
end
# ## Линейная сложность (обход массива) ###
def array_traversal(nums)
count = 0
# Число итераций пропорционально длине массива
for num in nums
count += 1
end
count
end
# ## Квадратичная сложность ###
def quadratic(n)
count = 0
# Число итераций квадратично зависит от размера данных n
for i in 0...n
for j in 0...n
count += 1
end
end
count
end
# ## Квадратичная сложность (пузырьковая сортировка) ###
def bubble_sort(nums)
count = 0 # Счетчик
# Внешний цикл: неотсортированный диапазон [0, i]
for i in (nums.length - 1).downto(0)
# Внутренний цикл: переместить максимальный элемент неотсортированного диапазона [0, i] в его правый конец
for j in 0...i
if nums[j] > nums[j + 1]
# Поменять местами nums[j] и nums[j + 1]
tmp = nums[j]
nums[j] = nums[j + 1]
nums[j + 1] = tmp
count += 3 # Обмен элементов включает 3 элементарные операции
end
end
end
count
end
# ## Экспоненциальная сложность (итеративная реализация) ###
def exponential(n)
count, base = 0, 1
# На каждом шаге клетка делится надвое, образуя последовательность 1, 2, 4, 8, ..., 2^(n-1)
(0...n).each do
(0...base).each { count += 1 }
base *= 2
end
# count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1
count
end
# ## Экспоненциальная сложность (рекурсивная реализация) ###
def exp_recur(n)
return 1 if n == 1
exp_recur(n - 1) + exp_recur(n - 1) + 1
end
# ## Логарифмическая сложность (итеративная реализация) ###
def logarithmic(n)
count = 0
while n > 1
n /= 2
count += 1
end
count
end
# ## Логарифмическая сложность (рекурсивная реализация) ###
def log_recur(n)
return 0 unless n > 1
log_recur(n / 2) + 1
end
# ## Линейно-логарифмическая сложность ###
def linear_log_recur(n)
return 1 unless n > 1
count = linear_log_recur(n / 2) + linear_log_recur(n / 2)
(0...n).each { count += 1 }
count
end
### Факториальная сложность (рекурсивная реализация) ### ### Факториальная сложность (рекурсивная реализация) ###
def factorial_recur(n) def factorial_recur(n)
return 1 if n == 0 return 1 if n == 0
@@ -4339,26 +3638,6 @@ $$
=== "Ruby" === "Ruby"
```ruby title="worst_best_time_complexity.rb" ```ruby title="worst_best_time_complexity.rb"
=begin
File: worst_best_time_complexity.rb
Created Time: 2024-03-30
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
# ## Создать массив с элементами: 1, 2, ..., n в случайном порядке ###
def random_numbers(n)
# Создать массив nums =: 1, 2, 3, ..., n
nums = Array.new(n) { |i| i + 1 }
# Случайно перемешать элементы массива
nums.shuffle!
end
=begin
File: worst_best_time_complexity.rb
Created Time: 2024-03-30
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
### Создать массив с элементами: 1, 2, ..., n в случайном порядке ### ### Создать массив с элементами: 1, 2, ..., n в случайном порядке ###
def random_numbers(n) def random_numbers(n)
# Создать массив nums =: 1, 2, 3, ..., n # Создать массив nums =: 1, 2, 3, ..., n
@@ -422,38 +422,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="binary_search_recur.rb" ```ruby title="binary_search_recur.rb"
=begin
File: binary_search_recur.rb
Created Time: 2024-05-13
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
# ## Бинарный поиск: задача f(i, j) ###
def dfs(nums, target, i, j)
# Если интервал пуст, целевой элемент отсутствует, вернуть -1
return -1 if i > j
# Вычислить индекс середины m
m = (i + j) / 2
if nums[m] < target
# Рекурсивная подзадача f(m+1, j)
return dfs(nums, target, m + 1, j)
elsif nums[m] > target
# Рекурсивная подзадача f(i, m-1)
return dfs(nums, target, i, m - 1)
else
# Целевой элемент найден, вернуть его индекс
return m
end
end
=begin
File: binary_search_recur.rb
Created Time: 2024-05-13
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
### Бинарный поиск: задача f(i, j) ### ### Бинарный поиск: задача f(i, j) ###
def dfs(nums, target, i, j) def dfs(nums, target, i, j)
# Если интервал пуст, целевой элемент отсутствует, вернуть -1 # Если интервал пуст, целевой элемент отсутствует, вернуть -1
@@ -485,42 +485,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="build_tree.rb" ```ruby title="build_tree.rb"
=begin
File: build_tree.rb
Created Time: 2024-05-13
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
require_relative '../utils/tree_node'
require_relative '../utils/print_util'
# ## Построить двоичное дерево: разделяй и властвуй ###
def dfs(preorder, inorder_map, i, l, r)
# Завершить при пустом диапазоне поддерева
return if r - l < 0
# Инициализировать корневой узел
root = TreeNode.new(preorder[i])
# Найти m, чтобы разделить левое и правое поддеревья
m = inorder_map[preorder[i]]
# Подзадача: построить левое поддерево
root.left = dfs(preorder, inorder_map, i + 1, l, m - 1)
# Подзадача: построить правое поддерево
root.right = dfs(preorder, inorder_map, i + 1 + m - l, m + 1, r)
# Вернуть корневой узел
root
end
=begin
File: build_tree.rb
Created Time: 2024-05-13
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
require_relative '../utils/tree_node'
require_relative '../utils/print_util'
### Построить двоичное дерево: разделяй и властвуй ### ### Построить двоичное дерево: разделяй и властвуй ###
def dfs(preorder, inorder_map, i, l, r) def dfs(preorder, inorder_map, i, l, r)
# Завершить при пустом диапазоне поддерева # Завершить при пустом диапазоне поддерева
@@ -510,56 +510,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="hanota.rb" ```ruby title="hanota.rb"
=begin
File: hanota.rb
Created Time: 2024-05-13
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
# ## Переместить один диск ###
def move(src, tar)
# Снять диск с вершины src
pan = src.pop
# Положить диск на вершину tar
tar << pan
end
=begin
File: hanota.rb
Created Time: 2024-05-13
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
# ## Переместить один диск ###
def move(src, tar)
# Снять диск с вершины src
pan = src.pop
# Положить диск на вершину tar
tar << pan
end
# ## Решить задачу Ханойской башни f(i) ###
def dfs(i, src, buf, tar)
# Если в src остался только один диск, сразу переместить его в tar
if i == 1
move(src, tar)
return
end
# Подзадача f(i-1): переместить верхние i-1 дисков из src в buf с помощью tar
dfs(i - 1, src, tar, buf)
# Подзадача f(1): переместить оставшийся один диск из src в tar
move(src, tar)
# Подзадача f(i-1): переместить верхние i-1 дисков из buf в tar с помощью src
dfs(i - 1, buf, src, tar)
end
=begin
File: hanota.rb
Created Time: 2024-05-13
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
### Переместить один диск ### ### Переместить один диск ###
def move(src, tar) def move(src, tar)
# Снять диск с вершины src # Снять диск с вершины src
@@ -304,12 +304,6 @@ $$
=== "Ruby" === "Ruby"
```ruby title="min_cost_climbing_stairs_dp.rb" ```ruby title="min_cost_climbing_stairs_dp.rb"
=begin
File: min_cost_climbing_stairs_dp.rb
Created Time: 2024-05-29
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
### Минимальная стоимость подъема по лестнице: динамическое программирование ### ### Минимальная стоимость подъема по лестнице: динамическое программирование ###
def min_cost_climbing_stairs_dp(cost) def min_cost_climbing_stairs_dp(cost)
n = cost.length - 1 n = cost.length - 1
@@ -564,12 +558,6 @@ $$
=== "Ruby" === "Ruby"
```ruby title="min_cost_climbing_stairs_dp.rb" ```ruby title="min_cost_climbing_stairs_dp.rb"
=begin
File: min_cost_climbing_stairs_dp.rb
Created Time: 2024-05-29
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
### Минимальная стоимость подъема по лестнице: динамическое программирование ### ### Минимальная стоимость подъема по лестнице: динамическое программирование ###
def min_cost_climbing_stairs_dp(cost) def min_cost_climbing_stairs_dp(cost)
n = cost.length - 1 n = cost.length - 1
@@ -935,12 +923,6 @@ $$
=== "Ruby" === "Ruby"
```ruby title="climbing_stairs_constraint_dp.rb" ```ruby title="climbing_stairs_constraint_dp.rb"
=begin
File: climbing_stairs_constraint_dp.rb
Created Time: 2024-05-29
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
### Подъем по лестнице с ограничениями: динамическое программирование ### ### Подъем по лестнице с ограничениями: динамическое программирование ###
def climbing_stairs_constraint_dp(n) def climbing_stairs_constraint_dp(n)
return 1 if n == 1 || n == 2 return 1 if n == 1 || n == 2
@@ -369,12 +369,6 @@ $$
=== "Ruby" === "Ruby"
```ruby title="min_path_sum.rb" ```ruby title="min_path_sum.rb"
=begin
File: min_path_sum.rb
Created Time: 2024-05-29
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
### Минимальная сумма пути: полный перебор ### ### Минимальная сумма пути: полный перебор ###
def min_path_sum_dfs(grid, i, j) def min_path_sum_dfs(grid, i, j)
# Если это верхняя левая ячейка, завершить поиск # Если это верхняя левая ячейка, завершить поиск
@@ -732,25 +726,6 @@ $$
=== "Ruby" === "Ruby"
```ruby title="min_path_sum.rb" ```ruby title="min_path_sum.rb"
=begin
File: min_path_sum.rb
Created Time: 2024-05-29
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
# ## Минимальная сумма пути: полный перебор ###
def min_path_sum_dfs(grid, i, j)
# Если это верхняя левая ячейка, завершить поиск
return grid[i][j] if i == 0 && j == 0
# Если индексы строки или столбца выходят за границы, вернуть стоимость +∞
return Float::INFINITY if i < 0 || j < 0
# Вычислить минимальную стоимость пути из левого верхнего угла до (i-1, j) и (i, j-1)
up = min_path_sum_dfs(grid, i - 1, j)
left = min_path_sum_dfs(grid, i, j - 1)
# Вернуть минимальную стоимость пути из левого верхнего угла до (i, j)
[left, up].min + grid[i][j]
end
### Минимальная сумма пути: поиск с мемоизацией ### ### Минимальная сумма пути: поиск с мемоизацией ###
def min_path_sum_dfs_mem(grid, mem, i, j) def min_path_sum_dfs_mem(grid, mem, i, j)
# Если это верхняя левая ячейка, завершить поиск # Если это верхняя левая ячейка, завершить поиск
@@ -1122,40 +1097,6 @@ $$
=== "Ruby" === "Ruby"
```ruby title="min_path_sum.rb" ```ruby title="min_path_sum.rb"
=begin
File: min_path_sum.rb
Created Time: 2024-05-29
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
# ## Минимальная сумма пути: полный перебор ###
def min_path_sum_dfs(grid, i, j)
# Если это верхняя левая ячейка, завершить поиск
return grid[i][j] if i == 0 && j == 0
# Если индексы строки или столбца выходят за границы, вернуть стоимость +∞
return Float::INFINITY if i < 0 || j < 0
# Вычислить минимальную стоимость пути из левого верхнего угла до (i-1, j) и (i, j-1)
up = min_path_sum_dfs(grid, i - 1, j)
left = min_path_sum_dfs(grid, i, j - 1)
# Вернуть минимальную стоимость пути из левого верхнего угла до (i, j)
[left, up].min + grid[i][j]
end
# ## Минимальная сумма пути: поиск с мемоизацией ###
def min_path_sum_dfs_mem(grid, mem, i, j)
# Если это верхняя левая ячейка, завершить поиск
return grid[0][0] if i == 0 && j == 0
# Если индексы строки или столбца выходят за границы, вернуть стоимость +∞
return Float::INFINITY if i < 0 || j < 0
# Если запись уже есть, вернуть сразу
return mem[i][j] if mem[i][j] != -1
# Минимальная стоимость пути для левой и верхней ячеек
up = min_path_sum_dfs_mem(grid, mem, i - 1, j)
left = min_path_sum_dfs_mem(grid, mem, i, j - 1)
# Сохранить и вернуть минимальную стоимость пути из левого верхнего угла до (i, j)
mem[i][j] = [left, up].min + grid[i][j]
end
### Минимальная сумма пути: динамическое программирование ### ### Минимальная сумма пути: динамическое программирование ###
def min_path_sum_dp(grid) def min_path_sum_dp(grid)
n, m = grid.length, grid.first.length n, m = grid.length, grid.first.length
@@ -1545,59 +1486,6 @@ $$
=== "Ruby" === "Ruby"
```ruby title="min_path_sum.rb" ```ruby title="min_path_sum.rb"
=begin
File: min_path_sum.rb
Created Time: 2024-05-29
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
# ## Минимальная сумма пути: полный перебор ###
def min_path_sum_dfs(grid, i, j)
# Если это верхняя левая ячейка, завершить поиск
return grid[i][j] if i == 0 && j == 0
# Если индексы строки или столбца выходят за границы, вернуть стоимость +∞
return Float::INFINITY if i < 0 || j < 0
# Вычислить минимальную стоимость пути из левого верхнего угла до (i-1, j) и (i, j-1)
up = min_path_sum_dfs(grid, i - 1, j)
left = min_path_sum_dfs(grid, i, j - 1)
# Вернуть минимальную стоимость пути из левого верхнего угла до (i, j)
[left, up].min + grid[i][j]
end
# ## Минимальная сумма пути: поиск с мемоизацией ###
def min_path_sum_dfs_mem(grid, mem, i, j)
# Если это верхняя левая ячейка, завершить поиск
return grid[0][0] if i == 0 && j == 0
# Если индексы строки или столбца выходят за границы, вернуть стоимость +∞
return Float::INFINITY if i < 0 || j < 0
# Если запись уже есть, вернуть сразу
return mem[i][j] if mem[i][j] != -1
# Минимальная стоимость пути для левой и верхней ячеек
up = min_path_sum_dfs_mem(grid, mem, i - 1, j)
left = min_path_sum_dfs_mem(grid, mem, i, j - 1)
# Сохранить и вернуть минимальную стоимость пути из левого верхнего угла до (i, j)
mem[i][j] = [left, up].min + grid[i][j]
end
# ## Минимальная сумма пути: динамическое программирование ###
def min_path_sum_dp(grid)
n, m = grid.length, grid.first.length
# Инициализация таблицы dp
dp = Array.new(n) { Array.new(m, 0) }
dp[0][0] = grid[0][0]
# Переход состояний: первая строка
(1...m).each { |j| dp[0][j] = dp[0][j - 1] + grid[0][j] }
# Переход состояний: первый столбец
(1...n).each { |i| dp[i][0] = dp[i - 1][0] + grid[i][0] }
# Переход состояний: остальные строки и столбцы
for i in 1...n
for j in 1...m
dp[i][j] = [dp[i][j - 1], dp[i - 1][j]].min + grid[i][j]
end
end
dp[n -1][m -1]
end
### Минимальная сумма пути: динамическое программирование с оптимизацией памяти ### ### Минимальная сумма пути: динамическое программирование с оптимизацией памяти ###
def min_path_sum_dp_comp(grid) def min_path_sum_dp_comp(grid)
n, m = grid.length, grid.first.length n, m = grid.length, grid.first.length
@@ -454,49 +454,6 @@ $$
=== "Ruby" === "Ruby"
```ruby title="edit_distance.rb" ```ruby title="edit_distance.rb"
=begin
File: edit_distance.rb
Created Time: 2024-05-29
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
# ## Редакционное расстояние: полный перебор ###
def edit_distance_dfs(s, t, i, j)
# Если s и t пусты, вернуть 0
return 0 if i == 0 && j == 0
# Если s пусто, вернуть длину t
return j if i == 0
# Если t пусто, вернуть длину s
return i if j == 0
# Если два символа равны, сразу пропустить их
return edit_distance_dfs(s, t, i - 1, j - 1) if s[i - 1] == t[j - 1]
# Минимальное число шагов редактирования = минимальное число шагов для вставки, удаления и замены + 1
insert = edit_distance_dfs(s, t, i, j - 1)
delete = edit_distance_dfs(s, t, i - 1, j)
replace = edit_distance_dfs(s, t, i - 1, j - 1)
# Вернуть минимальное число шагов редактирования
[insert, delete, replace].min + 1
end
def edit_distance_dfs_mem(s, t, mem, i, j)
# Если s и t пусты, вернуть 0
return 0 if i == 0 && j == 0
# Если s пусто, вернуть длину t
return j if i == 0
# Если t пусто, вернуть длину s
return i if j == 0
# Если запись уже есть, сразу вернуть ее
return mem[i][j] if mem[i][j] != -1
# Если два символа равны, сразу пропустить их
return edit_distance_dfs_mem(s, t, mem, i - 1, j - 1) if s[i - 1] == t[j - 1]
# Минимальное число шагов редактирования = минимальное число шагов для вставки, удаления и замены + 1
insert = edit_distance_dfs_mem(s, t, mem, i, j - 1)
delete = edit_distance_dfs_mem(s, t, mem, i - 1, j)
replace = edit_distance_dfs_mem(s, t, mem, i - 1, j - 1)
# Сохранить и вернуть минимальное число шагов редактирования
mem[i][j] = [insert, delete, replace].min + 1
end
### Редакционное расстояние: динамическое программирование ### ### Редакционное расстояние: динамическое программирование ###
def edit_distance_dp(s, t) def edit_distance_dp(s, t)
n, m = s.length, t.length n, m = s.length, t.length
@@ -981,71 +938,6 @@ $$
=== "Ruby" === "Ruby"
```ruby title="edit_distance.rb" ```ruby title="edit_distance.rb"
=begin
File: edit_distance.rb
Created Time: 2024-05-29
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
# ## Редакционное расстояние: полный перебор ###
def edit_distance_dfs(s, t, i, j)
# Если s и t пусты, вернуть 0
return 0 if i == 0 && j == 0
# Если s пусто, вернуть длину t
return j if i == 0
# Если t пусто, вернуть длину s
return i if j == 0
# Если два символа равны, сразу пропустить их
return edit_distance_dfs(s, t, i - 1, j - 1) if s[i - 1] == t[j - 1]
# Минимальное число шагов редактирования = минимальное число шагов для вставки, удаления и замены + 1
insert = edit_distance_dfs(s, t, i, j - 1)
delete = edit_distance_dfs(s, t, i - 1, j)
replace = edit_distance_dfs(s, t, i - 1, j - 1)
# Вернуть минимальное число шагов редактирования
[insert, delete, replace].min + 1
end
def edit_distance_dfs_mem(s, t, mem, i, j)
# Если s и t пусты, вернуть 0
return 0 if i == 0 && j == 0
# Если s пусто, вернуть длину t
return j if i == 0
# Если t пусто, вернуть длину s
return i if j == 0
# Если запись уже есть, сразу вернуть ее
return mem[i][j] if mem[i][j] != -1
# Если два символа равны, сразу пропустить их
return edit_distance_dfs_mem(s, t, mem, i - 1, j - 1) if s[i - 1] == t[j - 1]
# Минимальное число шагов редактирования = минимальное число шагов для вставки, удаления и замены + 1
insert = edit_distance_dfs_mem(s, t, mem, i, j - 1)
delete = edit_distance_dfs_mem(s, t, mem, i - 1, j)
replace = edit_distance_dfs_mem(s, t, mem, i - 1, j - 1)
# Сохранить и вернуть минимальное число шагов редактирования
mem[i][j] = [insert, delete, replace].min + 1
end
# ## Редакционное расстояние: динамическое программирование ###
def edit_distance_dp(s, t)
n, m = s.length, t.length
dp = Array.new(n + 1) { Array.new(m + 1, 0) }
# Переход состояний: первая строка и первый столбец
(1...(n + 1)).each { |i| dp[i][0] = i }
(1...(m + 1)).each { |j| dp[0][j] = j }
# Переход состояний: остальные строки и столбцы
for i in 1...(n + 1)
for j in 1...(m +1)
if s[i - 1] == t[j - 1]
# Если два символа равны, сразу пропустить их
dp[i][j] = dp[i - 1][j - 1]
else
# Минимальное число шагов редактирования = минимальное число шагов для вставки, удаления и замены + 1
dp[i][j] = [dp[i][j - 1], dp[i - 1][j], dp[i - 1][j - 1]].min + 1
end
end
end
dp[n][m]
end
### Редакционное расстояние: динамическое программирование с оптимизацией памяти ### ### Редакционное расстояние: динамическое программирование с оптимизацией памяти ###
def edit_distance_dp_comp(s, t) def edit_distance_dp_comp(s, t)
n, m = s.length, t.length n, m = s.length, t.length
@@ -395,33 +395,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="climbing_stairs_backtrack.rb" ```ruby title="climbing_stairs_backtrack.rb"
=begin
File: climbing_stairs_backtrack.rb
Created Time: 2024-05-29
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
# ## Бэктрекинг ###
def backtrack(choices, state, n, res)
# Когда подъем достигает n-й ступени, число вариантов увеличивается на 1
res[0] += 1 if state == n
# Перебор всех вариантов выбора
for choice in choices
# Отсечение: нельзя выходить за n-ю ступень
next if state + choice > n
# Попытка: сделать выбор и обновить состояние
backtrack(choices, state + choice, n, res)
end
# Откат
end
=begin
File: climbing_stairs_backtrack.rb
Created Time: 2024-05-29
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
### Бэктрекинг ### ### Бэктрекинг ###
def backtrack(choices, state, n, res) def backtrack(choices, state, n, res)
# Когда подъем достигает n-й ступени, число вариантов увеличивается на 1 # Когда подъем достигает n-й ступени, число вариантов увеличивается на 1
@@ -708,26 +681,6 @@ $$
=== "Ruby" === "Ruby"
```ruby title="climbing_stairs_dfs.rb" ```ruby title="climbing_stairs_dfs.rb"
=begin
File: climbing_stairs_dfs.rb
Created Time: 2024-05-29
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
# ## Поиск ###
def dfs(i)
# dp[1] и dp[2] уже известны, вернуть их
return i if i == 1 || i == 2
# dp[i] = dp[i-1] + dp[i-2]
dfs(i - 1) + dfs(i - 2)
end
=begin
File: climbing_stairs_dfs.rb
Created Time: 2024-05-29
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
### Поиск ### ### Поиск ###
def dfs(i) def dfs(i)
# dp[1] и dp[2] уже известны, вернуть их # dp[1] и dp[2] уже известны, вернуть их
@@ -1088,31 +1041,6 @@ $$
=== "Ruby" === "Ruby"
```ruby title="climbing_stairs_dfs_mem.rb" ```ruby title="climbing_stairs_dfs_mem.rb"
=begin
File: climbing_stairs_dfs_mem.rb
Created Time: 2024-05-29
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
# ## Поиск с мемоизацией ###
def dfs(i, mem)
# dp[1] и dp[2] уже известны, вернуть их
return i if i == 1 || i == 2
# Если запись dp[i] существует, сразу вернуть ее
return mem[i] if mem[i] != -1
# dp[i] = dp[i-1] + dp[i-2]
count = dfs(i - 1, mem) + dfs(i - 2, mem)
# Сохранить dp[i]
mem[i] = count
end
=begin
File: climbing_stairs_dfs_mem.rb
Created Time: 2024-05-29
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
### Поиск с мемоизацией ### ### Поиск с мемоизацией ###
def dfs(i, mem) def dfs(i, mem)
# dp[1] и dp[2] уже известны, вернуть их # dp[1] и dp[2] уже известны, вернуть их
@@ -1395,12 +1323,6 @@ $$
=== "Ruby" === "Ruby"
```ruby title="climbing_stairs_dp.rb" ```ruby title="climbing_stairs_dp.rb"
=begin
File: climbing_stairs_dp.rb
Created Time: 2024-05-29
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
### Подъем по лестнице: динамическое программирование ### ### Подъем по лестнице: динамическое программирование ###
def climbing_stairs_dp(n) def climbing_stairs_dp(n)
return n if n == 1 || n == 2 return n if n == 1 || n == 2
@@ -1642,26 +1564,6 @@ $$
=== "Ruby" === "Ruby"
```ruby title="climbing_stairs_dp.rb" ```ruby title="climbing_stairs_dp.rb"
=begin
File: climbing_stairs_dp.rb
Created Time: 2024-05-29
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
# ## Подъем по лестнице: динамическое программирование ###
def climbing_stairs_dp(n)
return n if n == 1 || n == 2
# Инициализация таблицы dp для хранения решений подзадач
dp = Array.new(n + 1, 0)
# Начальное состояние: заранее задать решения наименьших подзадач
dp[1], dp[2] = 1, 2
# Переход состояний: постепенное решение больших подзадач через меньшие
(3...(n + 1)).each { |i| dp[i] = dp[i - 1] + dp[i - 2] }
dp[n]
end
### Подъем по лестнице: динамическое программирование с оптимизацией памяти ### ### Подъем по лестнице: динамическое программирование с оптимизацией памяти ###
def climbing_stairs_dp_comp(n) def climbing_stairs_dp_comp(n)
return n if n == 1 || n == 2 return n if n == 1 || n == 2
@@ -324,12 +324,6 @@ $$
=== "Ruby" === "Ruby"
```ruby title="knapsack.rb" ```ruby title="knapsack.rb"
=begin
File: knapsack.rb
Created Time: 2024-05-29
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
### Рюкзак 0-1: полный перебор ### ### Рюкзак 0-1: полный перебор ###
def knapsack_dfs(wgt, val, i, c) def knapsack_dfs(wgt, val, i, c)
# Если все предметы уже рассмотрены или в рюкзаке не осталось места, вернуть стоимость 0 # Если все предметы уже рассмотрены или в рюкзаке не осталось места, вернуть стоимость 0
@@ -696,25 +690,6 @@ $$
=== "Ruby" === "Ruby"
```ruby title="knapsack.rb" ```ruby title="knapsack.rb"
=begin
File: knapsack.rb
Created Time: 2024-05-29
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
# ## Рюкзак 0-1: полный перебор ###
def knapsack_dfs(wgt, val, i, c)
# Если все предметы уже рассмотрены или в рюкзаке не осталось места, вернуть стоимость 0
return 0 if i == 0 || c == 0
# Если вместимость рюкзака превышена, можно только не класть предмет в рюкзак
return knapsack_dfs(wgt, val, i - 1, c) if wgt[i - 1] > c
# Вычислить максимальную стоимость для случаев, когда предмет i не кладут и кладут
no = knapsack_dfs(wgt, val, i - 1, c)
yes = knapsack_dfs(wgt, val, i - 1, c - wgt[i - 1]) + val[i - 1]
# Вернуть вариант с большей стоимостью из двух возможных
[no, yes].max
end
### Рюкзак 0-1: поиск с мемоизацией ### ### Рюкзак 0-1: поиск с мемоизацией ###
def knapsack_dfs_mem(wgt, val, mem, i, c) def knapsack_dfs_mem(wgt, val, mem, i, c)
# Если все предметы уже рассмотрены или в рюкзаке не осталось места, вернуть стоимость 0 # Если все предметы уже рассмотрены или в рюкзаке не осталось места, вернуть стоимость 0
@@ -1061,40 +1036,6 @@ $$
=== "Ruby" === "Ruby"
```ruby title="knapsack.rb" ```ruby title="knapsack.rb"
=begin
File: knapsack.rb
Created Time: 2024-05-29
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
# ## Рюкзак 0-1: полный перебор ###
def knapsack_dfs(wgt, val, i, c)
# Если все предметы уже рассмотрены или в рюкзаке не осталось места, вернуть стоимость 0
return 0 if i == 0 || c == 0
# Если вместимость рюкзака превышена, можно только не класть предмет в рюкзак
return knapsack_dfs(wgt, val, i - 1, c) if wgt[i - 1] > c
# Вычислить максимальную стоимость для случаев, когда предмет i не кладут и кладут
no = knapsack_dfs(wgt, val, i - 1, c)
yes = knapsack_dfs(wgt, val, i - 1, c - wgt[i - 1]) + val[i - 1]
# Вернуть вариант с большей стоимостью из двух возможных
[no, yes].max
end
# ## Рюкзак 0-1: поиск с мемоизацией ###
def knapsack_dfs_mem(wgt, val, mem, i, c)
# Если все предметы уже рассмотрены или в рюкзаке не осталось места, вернуть стоимость 0
return 0 if i == 0 || c == 0
# Если запись уже есть, вернуть сразу
return mem[i][c] if mem[i][c] != -1
# Если вместимость рюкзака превышена, можно только не класть предмет в рюкзак
return knapsack_dfs_mem(wgt, val, mem, i - 1, c) if wgt[i - 1] > c
# Вычислить максимальную стоимость для случаев, когда предмет i не кладут и кладут
no = knapsack_dfs_mem(wgt, val, mem, i - 1, c)
yes = knapsack_dfs_mem(wgt, val, mem, i - 1, c - wgt[i - 1]) + val[i - 1]
# Сохранить и вернуть вариант с большей стоимостью из двух решений
mem[i][c] = [no, yes].max
end
### Рюкзак 0-1: динамическое программирование ### ### Рюкзак 0-1: динамическое программирование ###
def knapsack_dp(wgt, val, cap) def knapsack_dp(wgt, val, cap)
n = wgt.length n = wgt.length
@@ -1476,60 +1417,6 @@ $$
=== "Ruby" === "Ruby"
```ruby title="knapsack.rb" ```ruby title="knapsack.rb"
=begin
File: knapsack.rb
Created Time: 2024-05-29
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
# ## Рюкзак 0-1: полный перебор ###
def knapsack_dfs(wgt, val, i, c)
# Если все предметы уже рассмотрены или в рюкзаке не осталось места, вернуть стоимость 0
return 0 if i == 0 || c == 0
# Если вместимость рюкзака превышена, можно только не класть предмет в рюкзак
return knapsack_dfs(wgt, val, i - 1, c) if wgt[i - 1] > c
# Вычислить максимальную стоимость для случаев, когда предмет i не кладут и кладут
no = knapsack_dfs(wgt, val, i - 1, c)
yes = knapsack_dfs(wgt, val, i - 1, c - wgt[i - 1]) + val[i - 1]
# Вернуть вариант с большей стоимостью из двух возможных
[no, yes].max
end
# ## Рюкзак 0-1: поиск с мемоизацией ###
def knapsack_dfs_mem(wgt, val, mem, i, c)
# Если все предметы уже рассмотрены или в рюкзаке не осталось места, вернуть стоимость 0
return 0 if i == 0 || c == 0
# Если запись уже есть, вернуть сразу
return mem[i][c] if mem[i][c] != -1
# Если вместимость рюкзака превышена, можно только не класть предмет в рюкзак
return knapsack_dfs_mem(wgt, val, mem, i - 1, c) if wgt[i - 1] > c
# Вычислить максимальную стоимость для случаев, когда предмет i не кладут и кладут
no = knapsack_dfs_mem(wgt, val, mem, i - 1, c)
yes = knapsack_dfs_mem(wgt, val, mem, i - 1, c - wgt[i - 1]) + val[i - 1]
# Сохранить и вернуть вариант с большей стоимостью из двух решений
mem[i][c] = [no, yes].max
end
# ## Рюкзак 0-1: динамическое программирование ###
def knapsack_dp(wgt, val, cap)
n = wgt.length
# Инициализация таблицы dp
dp = Array.new(n + 1) { Array.new(cap + 1, 0) }
# Переход состояний
for i in 1...(n + 1)
for c in 1...(cap + 1)
if wgt[i - 1] > c
# Если вместимость рюкзака превышена, предмет i не выбирать
dp[i][c] = dp[i - 1][c]
else
# Большее из двух решений: не брать или взять предмет i
dp[i][c] = [dp[i - 1][c], dp[i - 1][c - wgt[i - 1]] + val[i - 1]].max
end
end
end
dp[n][cap]
end
### Рюкзак 0-1: динамическое программирование с оптимизацией памяти ### ### Рюкзак 0-1: динамическое программирование с оптимизацией памяти ###
def knapsack_dp_comp(wgt, val, cap) def knapsack_dp_comp(wgt, val, cap)
n = wgt.length n = wgt.length
@@ -350,12 +350,6 @@ $$
=== "Ruby" === "Ruby"
```ruby title="unbounded_knapsack.rb" ```ruby title="unbounded_knapsack.rb"
=begin
File: unbounded_knapsack.rb
Created Time: 2024-05-29
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
### Полный рюкзак: динамическое программирование ### ### Полный рюкзак: динамическое программирование ###
def unbounded_knapsack_dp(wgt, val, cap) def unbounded_knapsack_dp(wgt, val, cap)
n = wgt.length n = wgt.length
@@ -709,12 +703,6 @@ $$
=== "Ruby" === "Ruby"
```ruby title="unbounded_knapsack.rb" ```ruby title="unbounded_knapsack.rb"
=begin
File: unbounded_knapsack.rb
Created Time: 2024-05-29
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
### Полный рюкзак: динамическое программирование ### ### Полный рюкзак: динамическое программирование ###
def unbounded_knapsack_dp(wgt, val, cap) def unbounded_knapsack_dp(wgt, val, cap)
n = wgt.length n = wgt.length
@@ -1180,12 +1168,6 @@ $$
=== "Ruby" === "Ruby"
```ruby title="coin_change.rb" ```ruby title="coin_change.rb"
=begin
File: coin_change.rb
Created Time: 2024-05-29
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
### Размен монет: динамическое программирование ### ### Размен монет: динамическое программирование ###
def coin_change_dp(coins, amt) def coin_change_dp(coins, amt)
n = coins.length n = coins.length
@@ -1601,35 +1583,6 @@ $$
=== "Ruby" === "Ruby"
```ruby title="coin_change.rb" ```ruby title="coin_change.rb"
=begin
File: coin_change.rb
Created Time: 2024-05-29
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
# ## Размен монет: динамическое программирование ###
def coin_change_dp(coins, amt)
n = coins.length
_MAX = amt + 1
# Инициализация таблицы dp
dp = Array.new(n + 1) { Array.new(amt + 1, 0) }
# Переход состояний: первая строка и первый столбец
(1...(amt + 1)).each { |a| dp[0][a] = _MAX }
# Переход состояний: остальные строки и столбцы
for i in 1...(n + 1)
for a in 1...(amt + 1)
if coins[i - 1] > a
# Если целевая сумма превышена, монету i не выбирать
dp[i][a] = dp[i - 1][a]
else
# Меньшее из двух решений: не брать или взять монету i
dp[i][a] = [dp[i - 1][a], dp[i][a - coins[i - 1]] + 1].min
end
end
end
dp[n][amt] != _MAX ? dp[n][amt] : -1
end
### Размен монет: динамическое программирование с оптимизацией памяти ### ### Размен монет: динамическое программирование с оптимизацией памяти ###
def coin_change_dp_comp(coins, amt) def coin_change_dp_comp(coins, amt)
n = coins.length n = coins.length
@@ -2033,12 +1986,6 @@ $$
=== "Ruby" === "Ruby"
```ruby title="coin_change_ii.rb" ```ruby title="coin_change_ii.rb"
=begin
File: coin_change_ii.rb
Created Time: 2024-05-29
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
### Размен монет II: динамическое программирование ### ### Размен монет II: динамическое программирование ###
def coin_change_ii_dp(coins, amt) def coin_change_ii_dp(coins, amt)
n = coins.length n = coins.length
@@ -2375,34 +2322,6 @@ $$
=== "Ruby" === "Ruby"
```ruby title="coin_change_ii.rb" ```ruby title="coin_change_ii.rb"
=begin
File: coin_change_ii.rb
Created Time: 2024-05-29
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
# ## Размен монет II: динамическое программирование ###
def coin_change_ii_dp(coins, amt)
n = coins.length
# Инициализация таблицы dp
dp = Array.new(n + 1) { Array.new(amt + 1, 0) }
# Инициализация первого столбца
(0...(n + 1)).each { |i| dp[i][0] = 1 }
# Переход состояний
for i in 1...(n + 1)
for a in 1...(amt + 1)
if coins[i - 1] > a
# Если целевая сумма превышена, монету i не выбирать
dp[i][a] = dp[i - 1][a]
else
# Сумма двух решений: не брать или взять монету i
dp[i][a] = dp[i - 1][a] + dp[i][a - coins[i - 1]]
end
end
end
dp[n][amt]
end
### Размен монет II: динамическое программирование с оптимизацией памяти ### ### Размен монет II: динамическое программирование с оптимизацией памяти ###
def coin_change_ii_dp_comp(coins, amt) def coin_change_ii_dp_comp(coins, amt)
n = coins.length n = coins.length
-16
View File
@@ -1130,14 +1130,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="graph_adjacency_matrix.rb" ```ruby title="graph_adjacency_matrix.rb"
=begin
File: graph_adjacency_matrix.rb
Created Time: 2024-04-25
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
require_relative '../utils/print_util'
### Класс неориентированного графа на основе матрицы смежности ### ### Класс неориентированного графа на основе матрицы смежности ###
class GraphAdjMat class GraphAdjMat
def initialize(vertices, edges) def initialize(vertices, edges)
@@ -2303,14 +2295,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="graph_adjacency_list.rb" ```ruby title="graph_adjacency_list.rb"
=begin
File: graph_adjacency_list.rb
Created Time: 2024-04-25
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
require_relative '../utils/vertex'
### Класс неориентированного графа на основе списка смежности ### ### Класс неориентированного графа на основе списка смежности ###
class GraphAdjList class GraphAdjList
attr_reader :adj_list attr_reader :adj_list
-42
View File
@@ -450,16 +450,6 @@ BFS обычно реализуется с помощью очереди, код
=== "Ruby" === "Ruby"
```ruby title="graph_bfs.rb" ```ruby title="graph_bfs.rb"
=begin
File: graph_bfs.rb
Created Time: 2024-04-25
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
require 'set'
require_relative './graph_adjacency_list'
require_relative '../utils/vertex'
### Обход в ширину ### ### Обход в ширину ###
def graph_bfs(graph, start_vet) def graph_bfs(graph, start_vet)
# Использовать список смежности для представления графа, чтобы получать все смежные вершины заданной вершины # Использовать список смежности для представления графа, чтобы получать все смежные вершины заданной вершины
@@ -921,38 +911,6 @@ BFS обычно реализуется с помощью очереди, код
=== "Ruby" === "Ruby"
```ruby title="graph_dfs.rb" ```ruby title="graph_dfs.rb"
=begin
File: graph_dfs.rb
Created Time: 2024-04-25
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
require 'set'
require_relative './graph_adjacency_list'
require_relative '../utils/vertex'
# ## Вспомогательная функция обхода в глубину ###
def dfs(graph, visited, res, vet)
res << vet # Отметить посещенную вершину
visited.add(vet) # Отметить эту вершину как посещенную
# Обойти все смежные вершины данной вершины
for adj_vet in graph.adj_list[vet]
next if visited.include?(adj_vet) # Пропустить уже посещенную вершину
# Рекурсивно обходить смежные вершины
dfs(graph, visited, res, adj_vet)
end
end
=begin
File: graph_dfs.rb
Created Time: 2024-04-25
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
require 'set'
require_relative './graph_adjacency_list'
require_relative '../utils/vertex'
### Вспомогательная функция обхода в глубину ### ### Вспомогательная функция обхода в глубину ###
def dfs(graph, visited, res, vet) def dfs(graph, visited, res, vet)
res << vet # Отметить посещенную вершину res << vet # Отметить посещенную вершину
@@ -496,29 +496,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="fractional_knapsack.rb" ```ruby title="fractional_knapsack.rb"
=begin
File: fractional_knapsack.rb
Created Time: 2024-05-07
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
# ## Предмет ###
class Item
attr_accessor :w # Вес предмета
attr_accessor :v # Стоимость предмета
def initialize(w, v)
@w = w
@v = v
end
end
=begin
File: fractional_knapsack.rb
Created Time: 2024-05-07
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
### Предмет ### ### Предмет ###
class Item class Item
attr_accessor :w # Вес предмета attr_accessor :w # Вес предмета
@@ -310,12 +310,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="coin_change_greedy.rb" ```ruby title="coin_change_greedy.rb"
=begin
File: coin_change_greedy.rb
Created Time: 2024-05-07
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
### Размен монет: жадный алгоритм ### ### Размен монет: жадный алгоритм ###
def coin_change_greedy(coins, amt) def coin_change_greedy(coins, amt)
# Предположить, что список coins упорядочен # Предположить, что список coins упорядочен
@@ -397,12 +397,6 @@ $$
=== "Ruby" === "Ruby"
```ruby title="max_capacity.rb" ```ruby title="max_capacity.rb"
=begin
File: max_capacity.rb
Created Time: 2024-05-07
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
### Максимальная вместимость: жадный алгоритм ### ### Максимальная вместимость: жадный алгоритм ###
def max_capacity(ht) def max_capacity(ht)
# Инициализировать i и j так, чтобы они располагались по двум концам массива # Инициализировать i и j так, чтобы они располагались по двум концам массива
@@ -371,12 +371,6 @@ $$
=== "Ruby" === "Ruby"
```ruby title="max_product_cutting.rb" ```ruby title="max_product_cutting.rb"
=begin
File: max_product_cutting.rb
Created Time: 2024-05-07
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
### Максимальное произведение разрезания: жадный алгоритм ### ### Максимальное произведение разрезания: жадный алгоритм ###
def max_product_cutting(n) def max_product_cutting(n)
# Когда n <= 3, обязательно нужно выделить одну 1 # Когда n <= 3, обязательно нужно выделить одну 1
-84
View File
@@ -601,90 +601,6 @@ index = hash(key) % capacity
=== "Ruby" === "Ruby"
```ruby title="simple_hash.rb" ```ruby title="simple_hash.rb"
=begin
File: simple_hash.rb
Created Time: 2024-04-14
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
# ## Аддитивное хеширование ###
def add_hash(key)
hash = 0
modulus = 1_000_000_007
key.each_char { |c| hash += c.ord }
hash % modulus
end
=begin
File: simple_hash.rb
Created Time: 2024-04-14
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
# ## Аддитивное хеширование ###
def add_hash(key)
hash = 0
modulus = 1_000_000_007
key.each_char { |c| hash += c.ord }
hash % modulus
end
# ## Мультипликативное хеширование ###
def mul_hash(key)
hash = 0
modulus = 1_000_000_007
key.each_char { |c| hash = 31 * hash + c.ord }
hash % modulus
end
=begin
File: simple_hash.rb
Created Time: 2024-04-14
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
# ## Аддитивное хеширование ###
def add_hash(key)
hash = 0
modulus = 1_000_000_007
key.each_char { |c| hash += c.ord }
hash % modulus
end
# ## Мультипликативное хеширование ###
def mul_hash(key)
hash = 0
modulus = 1_000_000_007
key.each_char { |c| hash = 31 * hash + c.ord }
hash % modulus
end
# ## XOR-хеширование ###
def xor_hash(key)
hash = 0
modulus = 1_000_000_007
key.each_char { |c| hash ^= c.ord }
hash % modulus
end
=begin
File: simple_hash.rb
Created Time: 2024-04-14
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
### Аддитивное хеширование ### ### Аддитивное хеширование ###
def add_hash(key) def add_hash(key)
hash = 0 hash = 0
-16
View File
@@ -1422,14 +1422,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="hash_map_chaining.rb" ```ruby title="hash_map_chaining.rb"
=begin
File: hash_map_chaining.rb
Created Time: 2024-04-13
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
require_relative './array_hash_map'
### Хеш-таблица с цепочками ### ### Хеш-таблица с цепочками ###
class HashMapChaining class HashMapChaining
### Конструктор ### ### Конструктор ###
@@ -3176,14 +3168,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="hash_map_open_addressing.rb" ```ruby title="hash_map_open_addressing.rb"
=begin
File: hash_map_open_addressing.rb
Created Time: 2024-04-13
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
require_relative './array_hash_map'
### Хеш-таблица с открытой адресацией ### ### Хеш-таблица с открытой адресацией ###
class HashMapOpenAddressing class HashMapOpenAddressing
TOMBSTONE = Pair.new(-1, '-1') # Удалить метку TOMBSTONE = Pair.new(-1, '-1') # Удалить метку
-22
View File
@@ -1677,28 +1677,6 @@ index = hash(key) % capacity
=== "Ruby" === "Ruby"
```ruby title="array_hash_map.rb" ```ruby title="array_hash_map.rb"
=begin
File: array_hash_map.rb
Created Time: 2024-04-13
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
# ## Пара ключ-значение ###
class Pair
attr_accessor :key, :val
def initialize(key, val)
@key = key
@val = val
end
end
=begin
File: array_hash_map.rb
Created Time: 2024-04-13
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
### Пара ключ-значение ### ### Пара ключ-значение ###
class Pair class Pair
attr_accessor :key, :val attr_accessor :key, :val
-12
View File
@@ -311,18 +311,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="my_heap.rb" ```ruby title="my_heap.rb"
=begin
File: my_heap.rb
Created Time: 2024-04-19
Author: Blue Bean (lonnnnnnner@gmail.com)
=end
require_relative '../utils/print_util'
# ## Максимальная куча ###
class MaxHeap
attr_reader :max_heap
### Конструктор, строящий кучу по входному списку ### ### Конструктор, строящий кучу по входному списку ###
def initialize(nums) def initialize(nums)
# Добавить элементы списка в кучу без изменений # Добавить элементы списка в кучу без изменений
-427
View File
@@ -669,87 +669,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="my_heap.rb" ```ruby title="my_heap.rb"
=begin
File: my_heap.rb
Created Time: 2024-04-19
Author: Blue Bean (lonnnnnnner@gmail.com)
=end
require_relative '../utils/print_util'
# ## Максимальная куча ###
class MaxHeap
attr_reader :max_heap
# ## Конструктор, строящий кучу по входному списку ###
def initialize(nums)
# Добавить элементы списка в кучу без изменений
@max_heap = nums
# Выполнить heapify для всех узлов, кроме листовых
parent(size - 1).downto(0) do |i|
sift_down(i)
end
end
# ## Получить индекс левого дочернего узла ###
def left(i)
2 * i + 1
end
=begin
File: my_heap.rb
Created Time: 2024-04-19
Author: Blue Bean (lonnnnnnner@gmail.com)
=end
require_relative '../utils/print_util'
# ## Максимальная куча ###
class MaxHeap
attr_reader :max_heap
# ## Конструктор, строящий кучу по входному списку ###
def initialize(nums)
# Добавить элементы списка в кучу без изменений
@max_heap = nums
# Выполнить heapify для всех узлов, кроме листовых
parent(size - 1).downto(0) do |i|
sift_down(i)
end
end
# ## Получить индекс левого дочернего узла ###
def left(i)
2 * i + 1
end
# ## Получить индекс правого дочернего узла ###
def right(i)
2 * i + 2
end
=begin
File: my_heap.rb
Created Time: 2024-04-19
Author: Blue Bean (lonnnnnnner@gmail.com)
=end
require_relative '../utils/print_util'
# ## Максимальная куча ###
class MaxHeap
attr_reader :max_heap
# ## Конструктор, строящий кучу по входному списку ###
def initialize(nums)
# Добавить элементы списка в кучу без изменений
@max_heap = nums
# Выполнить heapify для всех узлов, кроме листовых
parent(size - 1).downto(0) do |i|
sift_down(i)
end
end
### Получить индекс левого дочернего узла ### ### Получить индекс левого дочернего узла ###
def left(i) def left(i)
2 * i + 1 2 * i + 1
@@ -880,58 +799,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="my_heap.rb" ```ruby title="my_heap.rb"
=begin
File: my_heap.rb
Created Time: 2024-04-19
Author: Blue Bean (lonnnnnnner@gmail.com)
=end
require_relative '../utils/print_util'
# ## Максимальная куча ###
class MaxHeap
attr_reader :max_heap
# ## Конструктор, строящий кучу по входному списку ###
def initialize(nums)
# Добавить элементы списка в кучу без изменений
@max_heap = nums
# Выполнить heapify для всех узлов, кроме листовых
parent(size - 1).downto(0) do |i|
sift_down(i)
end
end
# ## Получить индекс левого дочернего узла ###
def left(i)
2 * i + 1
end
# ## Получить индекс правого дочернего узла ###
def right(i)
2 * i + 2
end
# ## Получить индекс родительского узла ###
def parent(i)
(i - 1) / 2 # Округление вниз при делении
end
# ## Обмен элементов ###
def swap(i, j)
@max_heap[i], @max_heap[j] = @max_heap[j], @max_heap[i]
end
# ## Получить размер кучи ###
def size
@max_heap.length
end
# ## Проверка, пуста ли куча ###
def is_empty?
size == 0
end
### Доступ к элементу на вершине кучи ### ### Доступ к элементу на вершине кучи ###
def peek def peek
@max_heap[0] @max_heap[0]
@@ -1320,128 +1187,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="my_heap.rb" ```ruby title="my_heap.rb"
=begin
File: my_heap.rb
Created Time: 2024-04-19
Author: Blue Bean (lonnnnnnner@gmail.com)
=end
require_relative '../utils/print_util'
# ## Максимальная куча ###
class MaxHeap
attr_reader :max_heap
# ## Конструктор, строящий кучу по входному списку ###
def initialize(nums)
# Добавить элементы списка в кучу без изменений
@max_heap = nums
# Выполнить heapify для всех узлов, кроме листовых
parent(size - 1).downto(0) do |i|
sift_down(i)
end
end
# ## Получить индекс левого дочернего узла ###
def left(i)
2 * i + 1
end
# ## Получить индекс правого дочернего узла ###
def right(i)
2 * i + 2
end
# ## Получить индекс родительского узла ###
def parent(i)
(i - 1) / 2 # Округление вниз при делении
end
# ## Обмен элементов ###
def swap(i, j)
@max_heap[i], @max_heap[j] = @max_heap[j], @max_heap[i]
end
# ## Получить размер кучи ###
def size
@max_heap.length
end
# ## Проверка, пуста ли куча ###
def is_empty?
size == 0
end
# ## Доступ к элементу на вершине кучи ###
def peek
@max_heap[0]
end
# ## Добавление элемента в кучу ###
def push(val)
# Добавление узла
@max_heap << val
# Просеивание снизу вверх
sift_up(size - 1)
end
=begin
File: my_heap.rb
Created Time: 2024-04-19
Author: Blue Bean (lonnnnnnner@gmail.com)
=end
require_relative '../utils/print_util'
# ## Максимальная куча ###
class MaxHeap
attr_reader :max_heap
# ## Конструктор, строящий кучу по входному списку ###
def initialize(nums)
# Добавить элементы списка в кучу без изменений
@max_heap = nums
# Выполнить heapify для всех узлов, кроме листовых
parent(size - 1).downto(0) do |i|
sift_down(i)
end
end
# ## Получить индекс левого дочернего узла ###
def left(i)
2 * i + 1
end
# ## Получить индекс правого дочернего узла ###
def right(i)
2 * i + 2
end
# ## Получить индекс родительского узла ###
def parent(i)
(i - 1) / 2 # Округление вниз при делении
end
# ## Обмен элементов ###
def swap(i, j)
@max_heap[i], @max_heap[j] = @max_heap[j], @max_heap[i]
end
# ## Получить размер кучи ###
def size
@max_heap.length
end
# ## Проверка, пуста ли куча ###
def is_empty?
size == 0
end
# ## Доступ к элементу на вершине кучи ###
def peek
@max_heap[0]
end
### Добавление элемента в кучу ### ### Добавление элемента в кучу ###
def push(val) def push(val)
# Добавление узла # Добавление узла
@@ -1989,178 +1734,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="my_heap.rb" ```ruby title="my_heap.rb"
=begin
File: my_heap.rb
Created Time: 2024-04-19
Author: Blue Bean (lonnnnnnner@gmail.com)
=end
require_relative '../utils/print_util'
# ## Максимальная куча ###
class MaxHeap
attr_reader :max_heap
# ## Конструктор, строящий кучу по входному списку ###
def initialize(nums)
# Добавить элементы списка в кучу без изменений
@max_heap = nums
# Выполнить heapify для всех узлов, кроме листовых
parent(size - 1).downto(0) do |i|
sift_down(i)
end
end
# ## Получить индекс левого дочернего узла ###
def left(i)
2 * i + 1
end
# ## Получить индекс правого дочернего узла ###
def right(i)
2 * i + 2
end
# ## Получить индекс родительского узла ###
def parent(i)
(i - 1) / 2 # Округление вниз при делении
end
# ## Обмен элементов ###
def swap(i, j)
@max_heap[i], @max_heap[j] = @max_heap[j], @max_heap[i]
end
# ## Получить размер кучи ###
def size
@max_heap.length
end
# ## Проверка, пуста ли куча ###
def is_empty?
size == 0
end
# ## Доступ к элементу на вершине кучи ###
def peek
@max_heap[0]
end
# ## Добавление элемента в кучу ###
def push(val)
# Добавление узла
@max_heap << val
# Просеивание снизу вверх
sift_up(size - 1)
end
# ## Начиная с узла i, выполнить просеивание снизу вверх ###
def sift_up(i)
loop do
# Получение родительского узла для узла i
p = parent(i)
# Завершить heapify, когда «корневой узел уже пройден» или «узел не требует исправления»
break if p < 0 || @max_heap[i] <= @max_heap[p]
# Поменять два узла местами
swap(i, p)
# Циклическое просеивание вверх
i = p
end
end
# ## Извлечение элемента из кучи ###
def pop
# Обработка пустого случая
raise IndexError, "куча пуста" if is_empty?
# Поменять корневой узел с самым правым листом местами (поменять первый и последний элементы)
swap(0, size - 1)
# Удаление узла
val = @max_heap.pop
# Просеивание сверху вниз
sift_down(0)
# Вернуть элемент с вершины кучи
val
end
=begin
File: my_heap.rb
Created Time: 2024-04-19
Author: Blue Bean (lonnnnnnner@gmail.com)
=end
require_relative '../utils/print_util'
# ## Максимальная куча ###
class MaxHeap
attr_reader :max_heap
# ## Конструктор, строящий кучу по входному списку ###
def initialize(nums)
# Добавить элементы списка в кучу без изменений
@max_heap = nums
# Выполнить heapify для всех узлов, кроме листовых
parent(size - 1).downto(0) do |i|
sift_down(i)
end
end
# ## Получить индекс левого дочернего узла ###
def left(i)
2 * i + 1
end
# ## Получить индекс правого дочернего узла ###
def right(i)
2 * i + 2
end
# ## Получить индекс родительского узла ###
def parent(i)
(i - 1) / 2 # Округление вниз при делении
end
# ## Обмен элементов ###
def swap(i, j)
@max_heap[i], @max_heap[j] = @max_heap[j], @max_heap[i]
end
# ## Получить размер кучи ###
def size
@max_heap.length
end
# ## Проверка, пуста ли куча ###
def is_empty?
size == 0
end
# ## Доступ к элементу на вершине кучи ###
def peek
@max_heap[0]
end
# ## Добавление элемента в кучу ###
def push(val)
# Добавление узла
@max_heap << val
# Просеивание снизу вверх
sift_up(size - 1)
end
# ## Начиная с узла i, выполнить просеивание снизу вверх ###
def sift_up(i)
loop do
# Получение родительского узла для узла i
p = parent(i)
# Завершить heapify, когда «корневой узел уже пройден» или «узел не требует исправления»
break if p < 0 || @max_heap[i] <= @max_heap[p]
# Поменять два узла местами
swap(i, p)
# Циклическое просеивание вверх
i = p
end
end
### Извлечение элемента из кучи ### ### Извлечение элемента из кучи ###
def pop def pop
# Обработка пустого случая # Обработка пустого случая
-32
View File
@@ -437,38 +437,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="top_k.rb" ```ruby title="top_k.rb"
=begin
File: top_k.rb
Created Time: 2024-04-19
Author: Blue Bean (lonnnnnnner@gmail.com)
=end
require_relative "./my_heap"
# ## Добавление элемента в кучу ###
def push_min_heap(heap, val)
# Инвертировать знак элемента
heap.push(-val)
end
# ## Извлечение элемента из кучи ###
def pop_min_heap(heap)
# Инвертировать знак элемента
-heap.pop
end
# ## Доступ к элементу на вершине кучи ###
def peek_min_heap(heap)
# Инвертировать знак элемента
-heap.peek
end
# ## Извлечение элементов из кучи ###
def get_min_heap(heap)
# Инвертировать все элементы кучи
heap.max_heap.map { |x| -x }
end
### Поиск k наибольших элементов массива с помощью кучи ### ### Поиск k наибольших элементов массива с помощью кучи ###
def top_k_heap(nums, k) def top_k_heap(nums, k)
# Инициализация минимальной кучи # Инициализация минимальной кучи
@@ -339,12 +339,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="binary_search.rb" ```ruby title="binary_search.rb"
=begin
File: binary_search.rb
Created Time: 2024-04-09
Author: Blue Bean (lonnnnnnner@gmail.com)
=end
### Бинарный поиск (двусторонне замкнутый интервал) ### ### Бинарный поиск (двусторонне замкнутый интервал) ###
def binary_search(nums, target) def binary_search(nums, target)
# Инициализировать двусторонне замкнутый интервал [0, n-1], то есть i и j указывают на первый и последний элементы массива соответственно # Инициализировать двусторонне замкнутый интервал [0, n-1], то есть i и j указывают на первый и последний элементы массива соответственно
@@ -669,34 +663,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="binary_search.rb" ```ruby title="binary_search.rb"
=begin
File: binary_search.rb
Created Time: 2024-04-09
Author: Blue Bean (lonnnnnnner@gmail.com)
=end
# ## Бинарный поиск (двусторонне замкнутый интервал) ###
def binary_search(nums, target)
# Инициализировать двусторонне замкнутый интервал [0, n-1], то есть i и j указывают на первый и последний элементы массива соответственно
i, j = 0, nums.length - 1
# Цикл завершается, когда диапазон поиска пуст (при i > j диапазон пуст)
while i <= j
# Теоретически числа в Ruby могут быть сколь угодно большими (ограничены только объемом памяти), поэтому не нужно учитывать переполнение больших чисел
m = (i + j) / 2 # Вычислить индекс середины m
if nums[m] < target
i = m + 1 # Это означает, что target находится в интервале [m+1, j]
elsif nums[m] > target
j = m - 1 # Это означает, что target находится в интервале [i, m-1]
else
return m # Целевой элемент найден, вернуть его индекс
end
end
-1 # Целевой элемент не найден, вернуть -1
end
### Бинарный поиск (лево замкнутый, право открытый интервал) ### ### Бинарный поиск (лево замкнутый, право открытый интервал) ###
def binary_search_lcro(nums, target) def binary_search_lcro(nums, target)
# Инициализировать лево замкнутый, право открытый интервал [0, n), то есть i и j указывают на первый элемент массива и позицию сразу за последним элементом соответственно # Инициализировать лево замкнутый, право открытый интервал [0, n), то есть i и j указывают на первый элемент массива и позицию сразу за последним элементом соответственно
@@ -212,14 +212,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="binary_search_edge.rb" ```ruby title="binary_search_edge.rb"
=begin
File: binary_search_edge.rb
Created Time: 2024-04-09
Author: Blue Bean (lonnnnnnner@gmail.com)
=end
require_relative './binary_search_insertion'
### Бинарный поиск самого левого target ### ### Бинарный поиск самого левого target ###
def binary_search_left_edge(nums, target) def binary_search_left_edge(nums, target)
# Эквивалентно поиску точки вставки target # Эквивалентно поиску точки вставки target
@@ -472,25 +464,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="binary_search_edge.rb" ```ruby title="binary_search_edge.rb"
=begin
File: binary_search_edge.rb
Created Time: 2024-04-09
Author: Blue Bean (lonnnnnnner@gmail.com)
=end
require_relative './binary_search_insertion'
# ## Бинарный поиск самого левого target ###
def binary_search_left_edge(nums, target)
# Эквивалентно поиску точки вставки target
i = binary_search_insertion(nums, target)
# target не найден, вернуть -1
return -1 if i == nums.length || nums[i] != target
i # Найти target и вернуть индекс i
end
### Бинарный поиск самого правого target ### ### Бинарный поиск самого правого target ###
def binary_search_right_edge(nums, target) def binary_search_right_edge(nums, target)
# Преобразовать задачу в поиск самого левого target + 1 # Преобразовать задачу в поиск самого левого target + 1
@@ -293,12 +293,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="binary_search_insertion.rb" ```ruby title="binary_search_insertion.rb"
=begin
File: binary_search_insertion.rb
Created Time: 2024-04-09
Author: Blue Bean (lonnnnnnner@gmail.com)
=end
### Бинарный поиск точки вставки (без повторяющихся элементов) ### ### Бинарный поиск точки вставки (без повторяющихся элементов) ###
def binary_search_insertion_simple(nums, target) def binary_search_insertion_simple(nums, target)
# Инициализировать двусторонне замкнутый интервал [0, n-1] # Инициализировать двусторонне замкнутый интервал [0, n-1]
@@ -644,33 +638,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="binary_search_insertion.rb" ```ruby title="binary_search_insertion.rb"
=begin
File: binary_search_insertion.rb
Created Time: 2024-04-09
Author: Blue Bean (lonnnnnnner@gmail.com)
=end
# ## Бинарный поиск точки вставки (без повторяющихся элементов) ###
def binary_search_insertion_simple(nums, target)
# Инициализировать двусторонне замкнутый интервал [0, n-1]
i, j = 0, nums.length - 1
while i <= j
# Вычислить индекс середины m
m = (i + j) / 2
if nums[m] < target
i = m + 1 # target находится в интервале [m+1, j]
elsif nums[m] > target
j = m - 1 # target находится в интервале [i, m-1]
else
return m # Найти target и вернуть точку вставки m
end
end
i # target не найден, вернуть точку вставки i
end
### Бинарный поиск точки вставки (с повторяющимися элементами) ### ### Бинарный поиск точки вставки (с повторяющимися элементами) ###
def binary_search_insertion(nums, target) def binary_search_insertion(nums, target)
# Инициализировать двусторонне замкнутый интервал [0, n-1] # Инициализировать двусторонне замкнутый интервал [0, n-1]
@@ -228,12 +228,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="two_sum.rb" ```ruby title="two_sum.rb"
=begin
File: two_sum.rb
Created Time: 2024-04-09
Author: Blue Bean (lonnnnnnner@gmail.com)
=end
### Метод 1: полный перебор ### ### Метод 1: полный перебор ###
def two_sum_brute_force(nums, target) def two_sum_brute_force(nums, target)
# Два вложенных цикла, временная сложность O(n^2) # Два вложенных цикла, временная сложность O(n^2)
@@ -527,24 +521,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="two_sum.rb" ```ruby title="two_sum.rb"
=begin
File: two_sum.rb
Created Time: 2024-04-09
Author: Blue Bean (lonnnnnnner@gmail.com)
=end
# ## Метод 1: полный перебор ###
def two_sum_brute_force(nums, target)
# Два вложенных цикла, временная сложность O(n^2)
for i in 0...(nums.length - 1)
for j in (i + 1)...nums.length
return [i, j] if nums[i] + nums[j] == target
end
end
[]
end
### Метод 2: вспомогательная хеш-таблица ### ### Метод 2: вспомогательная хеш-таблица ###
def two_sum_hash_table(nums, target) def two_sum_hash_table(nums, target)
# Вспомогательная хеш-таблица, пространственная сложность O(n) # Вспомогательная хеш-таблица, пространственная сложность O(n)
-27
View File
@@ -274,12 +274,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="bubble_sort.rb" ```ruby title="bubble_sort.rb"
=begin
File: bubble_sort.rb
Created Time: 2024-05-02
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
### Пузырьковая сортировка ### ### Пузырьковая сортировка ###
def bubble_sort(nums) def bubble_sort(nums)
n = nums.length n = nums.length
@@ -580,27 +574,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="bubble_sort.rb" ```ruby title="bubble_sort.rb"
=begin
File: bubble_sort.rb
Created Time: 2024-05-02
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
# ## Пузырьковая сортировка ###
def bubble_sort(nums)
n = nums.length
# Внешний цикл: неотсортированный диапазон [0, i]
for i in (n - 1).downto(1)
# Внутренний цикл: переместить максимальный элемент неотсортированного диапазона [0, i] в его правый конец
for j in 0...i
if nums[j] > nums[j + 1]
# Поменять местами nums[j] и nums[j + 1]
nums[j], nums[j + 1] = nums[j + 1], nums[j]
end
end
end
end
### Пузырьковая сортировка (оптимизация флагом) ### ### Пузырьковая сортировка (оптимизация флагом) ###
def bubble_sort_with_flag(nums) def bubble_sort_with_flag(nums)
n = nums.length n = nums.length
-6
View File
@@ -406,12 +406,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="bucket_sort.rb" ```ruby title="bucket_sort.rb"
=begin
File: bucket_sort.rb
Created Time: 2024-04-17
Author: Martin Xu (martin.xus@gmail.com)
=end
### Сортировка корзинами ### ### Сортировка корзинами ###
def bucket_sort(nums) def bucket_sort(nums)
# Инициализировать k = n/2 корзин, предполагая распределение 2 элементов в каждую корзину # Инициализировать k = n/2 корзин, предполагая распределение 2 элементов в каждую корзину
-32
View File
@@ -340,12 +340,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="counting_sort.rb" ```ruby title="counting_sort.rb"
=begin
File: counting_sort.rb
Created Time: 2024-05-02
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
### Сортировка подсчетом ### ### Сортировка подсчетом ###
def counting_sort_naive(nums) def counting_sort_naive(nums)
# Простая реализация, не подходит для сортировки объектов # Простая реализация, не подходит для сортировки объектов
@@ -857,32 +851,6 @@ $$
=== "Ruby" === "Ruby"
```ruby title="counting_sort.rb" ```ruby title="counting_sort.rb"
=begin
File: counting_sort.rb
Created Time: 2024-05-02
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
# ## Сортировка подсчетом ###
def counting_sort_naive(nums)
# Простая реализация, не подходит для сортировки объектов
# 1. Найти максимальный элемент массива m
m = 0
nums.each { |num| m = [m, num].max }
# 2. Подсчитать число появлений каждой цифры
# counter[num] обозначает число появлений num
counter = Array.new(m + 1, 0)
nums.each { |num| counter[num] += 1 }
# 3. Обойти counter и заполнить исходный массив nums элементами
i = 0
for num in 0...(m + 1)
(0...counter[num]).each do
nums[i] = num
i += 1
end
end
end
### Сортировка подсчетом ### ### Сортировка подсчетом ###
def counting_sort(nums) def counting_sort(nums)
# Полная реализация, позволяет сортировать объекты и является стабильной сортировкой # Полная реализация, позволяет сортировать объекты и является стабильной сортировкой
-30
View File
@@ -578,36 +578,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="heap_sort.rb" ```ruby title="heap_sort.rb"
=begin
File: heap_sort.rb
Created Time: 2024-04-10
Author: junminhong (junminhong1110@gmail.com)
=end
# ## Длина кучи равна n; начиная с узла i, выполнить просеивание сверху вниз ###
def sift_down(nums, n, i)
while true
# Определить узел с максимальным значением среди i, l и r и обозначить его как ma
l = 2 * i + 1
r = 2 * i + 2
ma = i
ma = l if l < n && nums[l] > nums[ma]
ma = r if r < n && nums[r] > nums[ma]
# Если узел i уже максимален или индексы l и r вне границ, дальнейшее просеивание не требуется, выйти
break if ma == i
# Поменять два узла местами
nums[i], nums[ma] = nums[ma], nums[i]
# Циклическое просеивание вниз
i = ma
end
end
=begin
File: heap_sort.rb
Created Time: 2024-04-10
Author: junminhong (junminhong1110@gmail.com)
=end
### Длина кучи равна n; начиная с узла i, выполнить просеивание сверху вниз ### ### Длина кучи равна n; начиная с узла i, выполнить просеивание сверху вниз ###
def sift_down(nums, n, i) def sift_down(nums, n, i)
while true while true
@@ -253,12 +253,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="insertion_sort.rb" ```ruby title="insertion_sort.rb"
=begin
File: insertion_sort.rb
Created Time: 2024-04-02
Author: Cy (3739004@gmail.com), Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
### Сортировка вставками ### ### Сортировка вставками ###
def insertion_sort(nums) def insertion_sort(nums)
n = nums.length n = nums.length
-47
View File
@@ -630,53 +630,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="merge_sort.rb" ```ruby title="merge_sort.rb"
=begin
File: merge_sort.rb
Created Time: 2024-04-10
Author: junminhong (junminhong1110@gmail.com)
=end
# ## Слияние левого и правого подмассивов ###
def merge(nums, left, mid, right)
# Интервал левого подмассива: [left, mid], правого подмассива: [mid+1, right]
# Создать временный массив tmp для хранения результата слияния
tmp = Array.new(right - left + 1, 0)
# Инициализировать начальные индексы левого и правого подмассивов
i, j, k = left, mid + 1, 0
# Пока в левом и правом подмассивах еще есть элементы, сравнивать их и копировать меньший во временный массив
while i <= mid && j <= right
if nums[i] <= nums[j]
tmp[k] = nums[i]
i += 1
else
tmp[k] = nums[j]
j += 1
end
k += 1
end
# Скопировать оставшиеся элементы левого и правого подмассивов во временный массив
while i <= mid
tmp[k] = nums[i]
i += 1
k += 1
end
while j <= right
tmp[k] = nums[j]
j += 1
k += 1
end
# Скопировать элементы временного массива tmp обратно в соответствующий диапазон исходного массива nums
(0...tmp.length).each do |k|
nums[left + k] = tmp[k]
end
end
=begin
File: merge_sort.rb
Created Time: 2024-04-10
Author: junminhong (junminhong1110@gmail.com)
=end
### Слияние левого и правого подмассивов ### ### Слияние левого и правого подмассивов ###
def merge(nums, left, mid, right) def merge(nums, left, mid, right)
# Интервал левого подмассива: [left, mid], правого подмассива: [mid+1, right] # Интервал левого подмассива: [left, mid], правого подмассива: [mid+1, right]
-257
View File
@@ -346,15 +346,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="quick_sort.rb" ```ruby title="quick_sort.rb"
=begin
File: quick_sort.rb
Created Time: 2024-04-01
Author: Cy (3739004@gmail.com), Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
# ## Класс быстрой сортировки ###
class QuickSort
class << self
### Разбиение с опорными указателями ### ### Разбиение с опорными указателями ###
def partition(nums, left, right) def partition(nums, left, right)
# Взять nums[left] в качестве опорного элемента # Взять nums[left] в качестве опорного элемента
@@ -588,34 +579,6 @@ class QuickSort
=== "Ruby" === "Ruby"
```ruby title="quick_sort.rb" ```ruby title="quick_sort.rb"
=begin
File: quick_sort.rb
Created Time: 2024-04-01
Author: Cy (3739004@gmail.com), Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
# ## Класс быстрой сортировки ###
class QuickSort
class << self
# ## Разбиение с опорными указателями ###
def partition(nums, left, right)
# Взять nums[left] в качестве опорного элемента
i, j = left, right
while i < j
while i < j && nums[j] >= nums[left]
j -= 1 # Идти справа налево в поисках первого элемента меньше опорного
end
while i < j && nums[i] <= nums[left]
i += 1 # Идти слева направо в поисках первого элемента больше опорного
end
# Обмен элементов
nums[i], nums[j] = nums[j], nums[i]
end
# Переместить опорный элемент на границу двух подмассивов
nums[i], nums[left] = nums[left], nums[i]
i # Вернуть индекс опорного элемента
end
### Класс быстрой сортировки ### ### Класс быстрой сортировки ###
def quick_sort(nums, left, right) def quick_sort(nums, left, right)
# Рекурсивно обрабатывать, пока длина подмассива не станет равной 1 # Рекурсивно обрабатывать, пока длина подмассива не станет равной 1
@@ -1085,109 +1048,6 @@ class QuickSort
=== "Ruby" === "Ruby"
```ruby title="quick_sort.rb" ```ruby title="quick_sort.rb"
=begin
File: quick_sort.rb
Created Time: 2024-04-01
Author: Cy (3739004@gmail.com), Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
# ## Класс быстрой сортировки ###
class QuickSort
class << self
# ## Разбиение с опорными указателями ###
def partition(nums, left, right)
# Взять nums[left] в качестве опорного элемента
i, j = left, right
while i < j
while i < j && nums[j] >= nums[left]
j -= 1 # Идти справа налево в поисках первого элемента меньше опорного
end
while i < j && nums[i] <= nums[left]
i += 1 # Идти слева направо в поисках первого элемента больше опорного
end
# Обмен элементов
nums[i], nums[j] = nums[j], nums[i]
end
# Переместить опорный элемент на границу двух подмассивов
nums[i], nums[left] = nums[left], nums[i]
i # Вернуть индекс опорного элемента
end
# ## Класс быстрой сортировки ###
def quick_sort(nums, left, right)
# Рекурсивно обрабатывать, пока длина подмассива не станет равной 1
if left < right
# Разбиение с опорными указателями
pivot = partition(nums, left, right)
# Рекурсивно обработать левый и правый подмассивы
quick_sort(nums, left, pivot - 1)
quick_sort(nums, pivot + 1, right)
end
nums
end
end
end
# ## Класс быстрой сортировки (оптимизация медианой) ###
class QuickSortMedian
class << self
# ## Выбрать медиану из трех кандидатов ###
def median_three(nums, left, mid, right)
# Выбрать медиану из трех кандидатов
_l, _m, _r = nums[left], nums[mid], nums[right]
# m находится между l и r
return mid if (_l <= _m && _m <= _r) || (_r <= _m && _m <= _l)
# l находится между m и r
return left if (_m <= _l && _l <= _r) || (_r <= _l && _l <= _m)
return right
end
=begin
File: quick_sort.rb
Created Time: 2024-04-01
Author: Cy (3739004@gmail.com), Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
# ## Класс быстрой сортировки ###
class QuickSort
class << self
# ## Разбиение с опорными указателями ###
def partition(nums, left, right)
# Взять nums[left] в качестве опорного элемента
i, j = left, right
while i < j
while i < j && nums[j] >= nums[left]
j -= 1 # Идти справа налево в поисках первого элемента меньше опорного
end
while i < j && nums[i] <= nums[left]
i += 1 # Идти слева направо в поисках первого элемента больше опорного
end
# Обмен элементов
nums[i], nums[j] = nums[j], nums[i]
end
# Переместить опорный элемент на границу двух подмассивов
nums[i], nums[left] = nums[left], nums[i]
i # Вернуть индекс опорного элемента
end
# ## Класс быстрой сортировки ###
def quick_sort(nums, left, right)
# Рекурсивно обрабатывать, пока длина подмассива не станет равной 1
if left < right
# Разбиение с опорными указателями
pivot = partition(nums, left, right)
# Рекурсивно обработать левый и правый подмассивы
quick_sort(nums, left, pivot - 1)
quick_sort(nums, pivot + 1, right)
end
nums
end
end
end
# ## Класс быстрой сортировки (оптимизация медианой) ###
class QuickSortMedian
class << self
### Выбрать медиану из трех кандидатов ### ### Выбрать медиану из трех кандидатов ###
def median_three(nums, left, mid, right) def median_three(nums, left, mid, right)
# Выбрать медиану из трех кандидатов # Выбрать медиану из трех кандидатов
@@ -1493,123 +1353,6 @@ class QuickSortMedian
=== "Ruby" === "Ruby"
```ruby title="quick_sort.rb" ```ruby title="quick_sort.rb"
=begin
File: quick_sort.rb
Created Time: 2024-04-01
Author: Cy (3739004@gmail.com), Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
# ## Класс быстрой сортировки ###
class QuickSort
class << self
# ## Разбиение с опорными указателями ###
def partition(nums, left, right)
# Взять nums[left] в качестве опорного элемента
i, j = left, right
while i < j
while i < j && nums[j] >= nums[left]
j -= 1 # Идти справа налево в поисках первого элемента меньше опорного
end
while i < j && nums[i] <= nums[left]
i += 1 # Идти слева направо в поисках первого элемента больше опорного
end
# Обмен элементов
nums[i], nums[j] = nums[j], nums[i]
end
# Переместить опорный элемент на границу двух подмассивов
nums[i], nums[left] = nums[left], nums[i]
i # Вернуть индекс опорного элемента
end
# ## Класс быстрой сортировки ###
def quick_sort(nums, left, right)
# Рекурсивно обрабатывать, пока длина подмассива не станет равной 1
if left < right
# Разбиение с опорными указателями
pivot = partition(nums, left, right)
# Рекурсивно обработать левый и правый подмассивы
quick_sort(nums, left, pivot - 1)
quick_sort(nums, pivot + 1, right)
end
nums
end
end
end
# ## Класс быстрой сортировки (оптимизация медианой) ###
class QuickSortMedian
class << self
# ## Выбрать медиану из трех кандидатов ###
def median_three(nums, left, mid, right)
# Выбрать медиану из трех кандидатов
_l, _m, _r = nums[left], nums[mid], nums[right]
# m находится между l и r
return mid if (_l <= _m && _m <= _r) || (_r <= _m && _m <= _l)
# l находится между m и r
return left if (_m <= _l && _l <= _r) || (_r <= _l && _l <= _m)
return right
end
# ## Разбиение с опорными указателями (медиана трех) ###
def partition(nums, left, right)
# ## Использовать nums[left] как опорный элемент
med = median_three(nums, left, (left + right) / 2, right)
# Переместить медиану в крайний левый элемент массива
nums[left], nums[med] = nums[med], nums[left]
i, j = left, right
while i < j
while i < j && nums[j] >= nums[left]
j -= 1 # Идти справа налево в поисках первого элемента меньше опорного
end
while i < j && nums[i] <= nums[left]
i += 1 # Идти слева направо в поисках первого элемента больше опорного
end
# Обмен элементов
nums[i], nums[j] = nums[j], nums[i]
end
# Переместить опорный элемент на границу двух подмассивов
nums[i], nums[left] = nums[left], nums[i]
i # Вернуть индекс опорного элемента
end
# ## Быстрая сортировка ###
def quick_sort(nums, left, right)
# Рекурсивно обрабатывать, пока длина подмассива не станет равной 1
if left < right
# Разбиение с опорными указателями
pivot = partition(nums, left, right)
# Рекурсивно обработать левый и правый подмассивы
quick_sort(nums, left, pivot - 1)
quick_sort(nums, pivot + 1, right)
end
nums
end
end
end
# ## Класс быстрой сортировки (оптимизация глубины рекурсии) ###
class QuickSortTailCall
class << self
# ## Разбиение с опорными указателями ###
def partition(nums, left, right)
# Использовать nums[left] как опорный элемент
i = left
j = right
while i < j
while i < j && nums[j] >= nums[left]
j -= 1 # Идти справа налево в поисках первого элемента меньше опорного
end
while i < j && nums[i] <= nums[left]
i += 1 # Идти слева направо в поисках первого элемента больше опорного
end
# Обмен элементов
nums[i], nums[j] = nums[j], nums[i]
end
# Переместить опорный элемент на границу двух подмассивов
nums[i], nums[left] = nums[left], nums[i]
i # Вернуть индекс опорного элемента
end
### Быстрая сортировка (оптимизация глубины рекурсии) ### ### Быстрая сортировка (оптимизация глубины рекурсии) ###
def quick_sort(nums, left, right) def quick_sort(nums, left, right)
# Рекурсивно обрабатывать, пока длина подмассива не станет равной 1 # Рекурсивно обрабатывать, пока длина подмассива не станет равной 1
-54
View File
@@ -669,60 +669,6 @@ $$
=== "Ruby" === "Ruby"
```ruby title="radix_sort.rb" ```ruby title="radix_sort.rb"
=begin
File: radix_sort.rb
Created Time: 2024-05-03
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
# ## Получить k-й разряд элемента num, где exp = 10^(k-1) ###
def digit(num, exp)
# Передача exp вместо k позволяет избежать повторного выполнения дорогостоящих вычислений степени
(num / exp) % 10
end
=begin
File: radix_sort.rb
Created Time: 2024-05-03
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
# ## Получить k-й разряд элемента num, где exp = 10^(k-1) ###
def digit(num, exp)
# Передача exp вместо k позволяет избежать повторного выполнения дорогостоящих вычислений степени
(num / exp) % 10
end
# ## Сортировка подсчетом (сортировка по k-му разряду nums) ###
def counting_sort_digit(nums, exp)
# Разряды десятичной системы лежат в диапазоне 0~9, поэтому нужен массив корзин длины 10
counter = Array.new(10, 0)
n = nums.length
# Подсчитать число появлений каждой цифры от 0 до 9
for i in 0...n
d = digit(nums[i], exp) # Получить k-й разряд nums[i], обозначив его как d
counter[d] += 1 # Подсчитать число появлений цифры d
end
# Вычислить префиксные суммы и преобразовать «число появлений» в «индекс массива»
(1...10).each { |i| counter[i] += counter[i - 1] }
# Выполняя обратный проход, заполнить res элементами по статистике в корзинах
res = Array.new(n, 0)
for i in (n - 1).downto(0)
d = digit(nums[i], exp)
j = counter[d] - 1 # Получить индекс j цифры d в массиве
res[j] = nums[i] # Поместить текущий элемент по индексу j
counter[d] -= 1 # Уменьшить количество d на 1
end
# Перезаписать исходный массив nums результатом
(0...n).each { |i| nums[i] = res[i] }
end
=begin
File: radix_sort.rb
Created Time: 2024-05-03
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
### Получить k-й разряд элемента num, где exp = 10^(k-1) ### ### Получить k-й разряд элемента num, где exp = 10^(k-1) ###
def digit(num, exp) def digit(num, exp)
# Передача exp вместо k позволяет избежать повторного выполнения дорогостоящих вычислений степени # Передача exp вместо k позволяет избежать повторного выполнения дорогостоящих вычислений степени
@@ -306,12 +306,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="selection_sort.rb" ```ruby title="selection_sort.rb"
=begin
File: selection_sort.rb
Created Time: 2024-05-03
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
### Сортировка выбором ### ### Сортировка выбором ###
def selection_sort(nums) def selection_sort(nums)
n = nums.length n = nums.length
-24
View File
@@ -2037,24 +2037,6 @@ comments: true
end end
end end
=begin
File: linkedlist_deque.rb
Created Time: 2024-04-06
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
# ## Узел двусвязного списка
class ListNode
attr_accessor :val
attr_accessor :next # Ссылка на узел-преемник
attr_accessor :prev # Ссылка на узел-предшественник
# ## Конструктор ###
def initialize(val)
@val = val
end
end
### Двусторонняя очередь на основе двусвязного списка ### ### Двусторонняя очередь на основе двусвязного списка ###
class LinkedListDeque class LinkedListDeque
### Получение длины двусторонней очереди ### ### Получение длины двусторонней очереди ###
@@ -3514,12 +3496,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="array_deque.rb" ```ruby title="array_deque.rb"
=begin
File: array_deque.rb
Created Time: 2024-04-05
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
### Двусторонняя очередь на основе кольцевого массива ### ### Двусторонняя очередь на основе кольцевого массива ###
class ArrayDeque class ArrayDeque
### Получение длины двусторонней очереди ### ### Получение длины двусторонней очереди ###
-14
View File
@@ -1246,14 +1246,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="linkedlist_queue.rb" ```ruby title="linkedlist_queue.rb"
=begin
File: linkedlist_queue.rb
Created Time: 2024-04-06
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
require_relative '../utils/list_node'
### Очередь на основе связного списка ### ### Очередь на основе связного списка ###
class LinkedListQueue class LinkedListQueue
### Получение длины очереди ### ### Получение длины очереди ###
@@ -2228,12 +2220,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="array_queue.rb" ```ruby title="array_queue.rb"
=begin
File: array_queue.rb
Created Time: 2024-04-05
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
### Очередь на основе кольцевого массива ### ### Очередь на основе кольцевого массива ###
class ArrayQueue class ArrayQueue
### Получение длины очереди ### ### Получение длины очереди ###
-14
View File
@@ -1109,14 +1109,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="linkedlist_stack.rb" ```ruby title="linkedlist_stack.rb"
=begin
File: linkedlist_stack.rb
Created Time: 2024-04-06
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
require_relative '../utils/list_node'
### Стек на основе связного списка ### ### Стек на основе связного списка ###
class LinkedListStack class LinkedListStack
attr_reader :size attr_reader :size
@@ -1766,12 +1758,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="array_stack.rb" ```ruby title="array_stack.rb"
=begin
File: array_stack.rb
Created Time: 2024-04-06
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
### Стек на основе массива ### ### Стек на основе массива ###
class ArrayStack class ArrayStack
### Конструктор ### ### Конструктор ###
@@ -1245,15 +1245,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="array_binary_tree.rb" ```ruby title="array_binary_tree.rb"
=begin
File: array_binary_tree.rb
Created Time: 2024-04-17
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
require_relative '../utils/tree_node'
require_relative '../utils/print_util'
### Класс двоичного дерева в массивном представлении ### ### Класс двоичного дерева в массивном представлении ###
class ArrayBinaryTree class ArrayBinaryTree
### Конструктор ### ### Конструктор ###
-719
View File
@@ -460,56 +460,6 @@ AVL-дерево одновременно является и двоичным
=== "Ruby" === "Ruby"
```ruby title="avl_tree.rb" ```ruby title="avl_tree.rb"
=begin
File: avl_tree.rb
Created Time: 2024-04-17
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
require_relative '../utils/tree_node'
require_relative '../utils/print_util'
# ## AVL-дерево ###
class AVLTree
# ## Конструктор ###
def initialize
@root = nil
end
# ## Получение корневого узла двоичного дерева ###
def get_root
@root
end
# ## Получить высоту узла ###
def height(node)
# Высота пустого узла равна -1, высота листового узла равна 0
return node.height unless node.nil?
-1
end
=begin
File: avl_tree.rb
Created Time: 2024-04-17
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
require_relative '../utils/tree_node'
require_relative '../utils/print_util'
# ## AVL-дерево ###
class AVLTree
# ## Конструктор ###
def initialize
@root = nil
end
# ## Получение корневого узла двоичного дерева ###
def get_root
@root
end
### Получить высоту узла ### ### Получить высоту узла ###
def height(node) def height(node)
# Высота пустого узла равна -1, высота листового узла равна 0 # Высота пустого узла равна -1, высота листового узла равна 0
@@ -686,41 +636,6 @@ AVL-дерево одновременно является и двоичным
=== "Ruby" === "Ruby"
```ruby title="avl_tree.rb" ```ruby title="avl_tree.rb"
=begin
File: avl_tree.rb
Created Time: 2024-04-17
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
require_relative '../utils/tree_node'
require_relative '../utils/print_util'
# ## AVL-дерево ###
class AVLTree
# ## Конструктор ###
def initialize
@root = nil
end
# ## Получение корневого узла двоичного дерева ###
def get_root
@root
end
# ## Получить высоту узла ###
def height(node)
# Высота пустого узла равна -1, высота листового узла равна 0
return node.height unless node.nil?
-1
end
# ## Обновить высоту узла ###
def update_height(node)
# Высота узла равна высоте более высокого поддерева + 1
node.height = [height(node.left), height(node.right)].max + 1
end
### Получить коэффициент баланса ### ### Получить коэффициент баланса ###
def balance_factor(node) def balance_factor(node)
# Коэффициент баланса пустого узла равен 0 # Коэффициент баланса пустого узла равен 0
@@ -991,50 +906,6 @@ AVL-дерево одновременно является и двоичным
=== "Ruby" === "Ruby"
```ruby title="avl_tree.rb" ```ruby title="avl_tree.rb"
=begin
File: avl_tree.rb
Created Time: 2024-04-17
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
require_relative '../utils/tree_node'
require_relative '../utils/print_util'
# ## AVL-дерево ###
class AVLTree
# ## Конструктор ###
def initialize
@root = nil
end
# ## Получение корневого узла двоичного дерева ###
def get_root
@root
end
# ## Получить высоту узла ###
def height(node)
# Высота пустого узла равна -1, высота листового узла равна 0
return node.height unless node.nil?
-1
end
# ## Обновить высоту узла ###
def update_height(node)
# Высота узла равна высоте более высокого поддерева + 1
node.height = [height(node.left), height(node.right)].max + 1
end
# ## Получить коэффициент баланса ###
def balance_factor(node)
# Коэффициент баланса пустого узла равен 0
return 0 if node.nil?
# Коэффициент баланса узла = высота левого поддерева - высота правого поддерева
height(node.left) - height(node.right)
end
### Операция правого вращения ### ### Операция правого вращения ###
def right_rotate(node) def right_rotate(node)
child = node.left child = node.left
@@ -1290,64 +1161,6 @@ AVL-дерево одновременно является и двоичным
=== "Ruby" === "Ruby"
```ruby title="avl_tree.rb" ```ruby title="avl_tree.rb"
=begin
File: avl_tree.rb
Created Time: 2024-04-17
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
require_relative '../utils/tree_node'
require_relative '../utils/print_util'
# ## AVL-дерево ###
class AVLTree
# ## Конструктор ###
def initialize
@root = nil
end
# ## Получение корневого узла двоичного дерева ###
def get_root
@root
end
# ## Получить высоту узла ###
def height(node)
# Высота пустого узла равна -1, высота листового узла равна 0
return node.height unless node.nil?
-1
end
# ## Обновить высоту узла ###
def update_height(node)
# Высота узла равна высоте более высокого поддерева + 1
node.height = [height(node.left), height(node.right)].max + 1
end
# ## Получить коэффициент баланса ###
def balance_factor(node)
# Коэффициент баланса пустого узла равен 0
return 0 if node.nil?
# Коэффициент баланса узла = высота левого поддерева - высота правого поддерева
height(node.left) - height(node.right)
end
# ## Операция правого вращения ###
def right_rotate(node)
child = node.left
grand_child = child.right
# Выполнить правое вращение узла node вокруг child
child.right = node
node.left = grand_child
# Обновить высоту узла
update_height(node)
update_height(child)
# Вернуть корневой узел поддерева после вращения
child
end
### Операция левого вращения ### ### Операция левого вращения ###
def left_rotate(node) def left_rotate(node)
child = node.right child = node.right
@@ -1816,78 +1629,6 @@ AVL-дерево одновременно является и двоичным
=== "Ruby" === "Ruby"
```ruby title="avl_tree.rb" ```ruby title="avl_tree.rb"
=begin
File: avl_tree.rb
Created Time: 2024-04-17
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
require_relative '../utils/tree_node'
require_relative '../utils/print_util'
# ## AVL-дерево ###
class AVLTree
# ## Конструктор ###
def initialize
@root = nil
end
# ## Получение корневого узла двоичного дерева ###
def get_root
@root
end
# ## Получить высоту узла ###
def height(node)
# Высота пустого узла равна -1, высота листового узла равна 0
return node.height unless node.nil?
-1
end
# ## Обновить высоту узла ###
def update_height(node)
# Высота узла равна высоте более высокого поддерева + 1
node.height = [height(node.left), height(node.right)].max + 1
end
# ## Получить коэффициент баланса ###
def balance_factor(node)
# Коэффициент баланса пустого узла равен 0
return 0 if node.nil?
# Коэффициент баланса узла = высота левого поддерева - высота правого поддерева
height(node.left) - height(node.right)
end
# ## Операция правого вращения ###
def right_rotate(node)
child = node.left
grand_child = child.right
# Выполнить правое вращение узла node вокруг child
child.right = node
node.left = grand_child
# Обновить высоту узла
update_height(node)
update_height(child)
# Вернуть корневой узел поддерева после вращения
child
end
# ## Операция левого вращения ###
def left_rotate(node)
child = node.right
grand_child = child.left
# Выполнить левое вращение узла node вокруг child
child.left = node
node.right = grand_child
# Обновить высоту узла
update_height(node)
update_height(child)
# Вернуть корневой узел поддерева после вращения
child
end
### Выполнить вращение, чтобы снова сбалансировать поддерево ### ### Выполнить вращение, чтобы снова сбалансировать поддерево ###
def rotate(node) def rotate(node)
# Получить коэффициент баланса узла node # Получить коэффициент баланса узла node
@@ -2272,213 +2013,6 @@ AVL-дерево одновременно является и двоичным
=== "Ruby" === "Ruby"
```ruby title="avl_tree.rb" ```ruby title="avl_tree.rb"
=begin
File: avl_tree.rb
Created Time: 2024-04-17
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
require_relative '../utils/tree_node'
require_relative '../utils/print_util'
# ## AVL-дерево ###
class AVLTree
# ## Конструктор ###
def initialize
@root = nil
end
# ## Получение корневого узла двоичного дерева ###
def get_root
@root
end
# ## Получить высоту узла ###
def height(node)
# Высота пустого узла равна -1, высота листового узла равна 0
return node.height unless node.nil?
-1
end
# ## Обновить высоту узла ###
def update_height(node)
# Высота узла равна высоте более высокого поддерева + 1
node.height = [height(node.left), height(node.right)].max + 1
end
# ## Получить коэффициент баланса ###
def balance_factor(node)
# Коэффициент баланса пустого узла равен 0
return 0 if node.nil?
# Коэффициент баланса узла = высота левого поддерева - высота правого поддерева
height(node.left) - height(node.right)
end
# ## Операция правого вращения ###
def right_rotate(node)
child = node.left
grand_child = child.right
# Выполнить правое вращение узла node вокруг child
child.right = node
node.left = grand_child
# Обновить высоту узла
update_height(node)
update_height(child)
# Вернуть корневой узел поддерева после вращения
child
end
# ## Операция левого вращения ###
def left_rotate(node)
child = node.right
grand_child = child.left
# Выполнить левое вращение узла node вокруг child
child.left = node
node.right = grand_child
# Обновить высоту узла
update_height(node)
update_height(child)
# Вернуть корневой узел поддерева после вращения
child
end
# ## Выполнить вращение, чтобы снова сбалансировать поддерево ###
def rotate(node)
# Получить коэффициент баланса узла node
balance_factor = balance_factor(node)
# Обойти левое поддерево
if balance_factor > 1
if balance_factor(node.left) >= 0
# Правое вращение
return right_rotate(node)
else
# Сначала левое вращение, затем правое
node.left = left_rotate(node.left)
return right_rotate(node)
end
# Правостороннее дерево обхода
elsif balance_factor < -1
if balance_factor(node.right) <= 0
# Левое вращение
return left_rotate(node)
else
# Сначала правое вращение, затем левое
node.right = right_rotate(node.right)
return left_rotate(node)
end
end
# Дерево сбалансировано, вращение не требуется, вернуть сразу
node
end
# ## Вставка узла ###
def insert(val)
@root = insert_helper(@root, val)
end
=begin
File: avl_tree.rb
Created Time: 2024-04-17
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
require_relative '../utils/tree_node'
require_relative '../utils/print_util'
# ## AVL-дерево ###
class AVLTree
# ## Конструктор ###
def initialize
@root = nil
end
# ## Получение корневого узла двоичного дерева ###
def get_root
@root
end
# ## Получить высоту узла ###
def height(node)
# Высота пустого узла равна -1, высота листового узла равна 0
return node.height unless node.nil?
-1
end
# ## Обновить высоту узла ###
def update_height(node)
# Высота узла равна высоте более высокого поддерева + 1
node.height = [height(node.left), height(node.right)].max + 1
end
# ## Получить коэффициент баланса ###
def balance_factor(node)
# Коэффициент баланса пустого узла равен 0
return 0 if node.nil?
# Коэффициент баланса узла = высота левого поддерева - высота правого поддерева
height(node.left) - height(node.right)
end
# ## Операция правого вращения ###
def right_rotate(node)
child = node.left
grand_child = child.right
# Выполнить правое вращение узла node вокруг child
child.right = node
node.left = grand_child
# Обновить высоту узла
update_height(node)
update_height(child)
# Вернуть корневой узел поддерева после вращения
child
end
# ## Операция левого вращения ###
def left_rotate(node)
child = node.right
grand_child = child.left
# Выполнить левое вращение узла node вокруг child
child.left = node
node.right = grand_child
# Обновить высоту узла
update_height(node)
update_height(child)
# Вернуть корневой узел поддерева после вращения
child
end
# ## Выполнить вращение, чтобы снова сбалансировать поддерево ###
def rotate(node)
# Получить коэффициент баланса узла node
balance_factor = balance_factor(node)
# Обойти левое поддерево
if balance_factor > 1
if balance_factor(node.left) >= 0
# Правое вращение
return right_rotate(node)
else
# Сначала левое вращение, затем правое
node.left = left_rotate(node.left)
return right_rotate(node)
end
# Правостороннее дерево обхода
elsif balance_factor < -1
if balance_factor(node.right) <= 0
# Левое вращение
return left_rotate(node)
else
# Сначала правое вращение, затем левое
node.right = right_rotate(node.right)
return left_rotate(node)
end
end
# Дерево сбалансировано, вращение не требуется, вернуть сразу
node
end
### Вставка узла ### ### Вставка узла ###
def insert(val) def insert(val)
@root = insert_helper(@root, val) @root = insert_helper(@root, val)
@@ -3067,259 +2601,6 @@ AVL-дерево одновременно является и двоичным
=== "Ruby" === "Ruby"
```ruby title="avl_tree.rb" ```ruby title="avl_tree.rb"
=begin
File: avl_tree.rb
Created Time: 2024-04-17
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
require_relative '../utils/tree_node'
require_relative '../utils/print_util'
# ## AVL-дерево ###
class AVLTree
# ## Конструктор ###
def initialize
@root = nil
end
# ## Получение корневого узла двоичного дерева ###
def get_root
@root
end
# ## Получить высоту узла ###
def height(node)
# Высота пустого узла равна -1, высота листового узла равна 0
return node.height unless node.nil?
-1
end
# ## Обновить высоту узла ###
def update_height(node)
# Высота узла равна высоте более высокого поддерева + 1
node.height = [height(node.left), height(node.right)].max + 1
end
# ## Получить коэффициент баланса ###
def balance_factor(node)
# Коэффициент баланса пустого узла равен 0
return 0 if node.nil?
# Коэффициент баланса узла = высота левого поддерева - высота правого поддерева
height(node.left) - height(node.right)
end
# ## Операция правого вращения ###
def right_rotate(node)
child = node.left
grand_child = child.right
# Выполнить правое вращение узла node вокруг child
child.right = node
node.left = grand_child
# Обновить высоту узла
update_height(node)
update_height(child)
# Вернуть корневой узел поддерева после вращения
child
end
# ## Операция левого вращения ###
def left_rotate(node)
child = node.right
grand_child = child.left
# Выполнить левое вращение узла node вокруг child
child.left = node
node.right = grand_child
# Обновить высоту узла
update_height(node)
update_height(child)
# Вернуть корневой узел поддерева после вращения
child
end
# ## Выполнить вращение, чтобы снова сбалансировать поддерево ###
def rotate(node)
# Получить коэффициент баланса узла node
balance_factor = balance_factor(node)
# Обойти левое поддерево
if balance_factor > 1
if balance_factor(node.left) >= 0
# Правое вращение
return right_rotate(node)
else
# Сначала левое вращение, затем правое
node.left = left_rotate(node.left)
return right_rotate(node)
end
# Правостороннее дерево обхода
elsif balance_factor < -1
if balance_factor(node.right) <= 0
# Левое вращение
return left_rotate(node)
else
# Сначала правое вращение, затем левое
node.right = right_rotate(node.right)
return left_rotate(node)
end
end
# Дерево сбалансировано, вращение не требуется, вернуть сразу
node
end
# ## Вставка узла ###
def insert(val)
@root = insert_helper(@root, val)
end
# ## Рекурсивная вставка узла (вспомогательный метод) ###
def insert_helper(node, val)
return TreeNode.new(val) if node.nil?
# 1. Найти позицию вставки и вставить узел
if val < node.val
node.left = insert_helper(node.left, val)
elsif val > node.val
node.right = insert_helper(node.right, val)
else
# Повторяющийся узел не вставлять, сразу вернуть
return node
end
# Обновить высоту узла
update_height(node)
# 2. Выполнить вращение, чтобы снова сбалансировать поддерево
rotate(node)
end
# ## Удаление узла ###
def remove(val)
@root = remove_helper(@root, val)
end
=begin
File: avl_tree.rb
Created Time: 2024-04-17
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
require_relative '../utils/tree_node'
require_relative '../utils/print_util'
# ## AVL-дерево ###
class AVLTree
# ## Конструктор ###
def initialize
@root = nil
end
# ## Получение корневого узла двоичного дерева ###
def get_root
@root
end
# ## Получить высоту узла ###
def height(node)
# Высота пустого узла равна -1, высота листового узла равна 0
return node.height unless node.nil?
-1
end
# ## Обновить высоту узла ###
def update_height(node)
# Высота узла равна высоте более высокого поддерева + 1
node.height = [height(node.left), height(node.right)].max + 1
end
# ## Получить коэффициент баланса ###
def balance_factor(node)
# Коэффициент баланса пустого узла равен 0
return 0 if node.nil?
# Коэффициент баланса узла = высота левого поддерева - высота правого поддерева
height(node.left) - height(node.right)
end
# ## Операция правого вращения ###
def right_rotate(node)
child = node.left
grand_child = child.right
# Выполнить правое вращение узла node вокруг child
child.right = node
node.left = grand_child
# Обновить высоту узла
update_height(node)
update_height(child)
# Вернуть корневой узел поддерева после вращения
child
end
# ## Операция левого вращения ###
def left_rotate(node)
child = node.right
grand_child = child.left
# Выполнить левое вращение узла node вокруг child
child.left = node
node.right = grand_child
# Обновить высоту узла
update_height(node)
update_height(child)
# Вернуть корневой узел поддерева после вращения
child
end
# ## Выполнить вращение, чтобы снова сбалансировать поддерево ###
def rotate(node)
# Получить коэффициент баланса узла node
balance_factor = balance_factor(node)
# Обойти левое поддерево
if balance_factor > 1
if balance_factor(node.left) >= 0
# Правое вращение
return right_rotate(node)
else
# Сначала левое вращение, затем правое
node.left = left_rotate(node.left)
return right_rotate(node)
end
# Правостороннее дерево обхода
elsif balance_factor < -1
if balance_factor(node.right) <= 0
# Левое вращение
return left_rotate(node)
else
# Сначала правое вращение, затем левое
node.right = right_rotate(node.right)
return left_rotate(node)
end
end
# Дерево сбалансировано, вращение не требуется, вернуть сразу
node
end
# ## Вставка узла ###
def insert(val)
@root = insert_helper(@root, val)
end
# ## Рекурсивная вставка узла (вспомогательный метод) ###
def insert_helper(node, val)
return TreeNode.new(val) if node.nil?
# 1. Найти позицию вставки и вставить узел
if val < node.val
node.left = insert_helper(node.left, val)
elsif val > node.val
node.right = insert_helper(node.right, val)
else
# Повторяющийся узел не вставлять, сразу вернуть
return node
end
# Обновить высоту узла
update_height(node)
# 2. Выполнить вращение, чтобы снова сбалансировать поддерево
rotate(node)
end
### Удаление узла ### ### Удаление узла ###
def remove(val) def remove(val)
@root = remove_helper(@root, val) @root = remove_helper(@root, val)
-141
View File
@@ -316,28 +316,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="binary_search_tree.rb" ```ruby title="binary_search_tree.rb"
=begin
File: binary_search_tree.rb
Created Time: 2024-04-18
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
require_relative '../utils/tree_node'
require_relative '../utils/print_util'
# ## Двоичное дерево поиска ###
class BinarySearchTree
# ## Конструктор ###
def initialize
# Инициализировать пустое дерево
@root = nil
end
# ## Получение корневого узла двоичного дерева ###
def get_root
@root
end
### Поиск узла ### ### Поиск узла ###
def search(num) def search(num)
cur = @root cur = @root
@@ -790,49 +768,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="binary_search_tree.rb" ```ruby title="binary_search_tree.rb"
=begin
File: binary_search_tree.rb
Created Time: 2024-04-18
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
require_relative '../utils/tree_node'
require_relative '../utils/print_util'
# ## Двоичное дерево поиска ###
class BinarySearchTree
# ## Конструктор ###
def initialize
# Инициализировать пустое дерево
@root = nil
end
# ## Получение корневого узла двоичного дерева ###
def get_root
@root
end
# ## Поиск узла ###
def search(num)
cur = @root
# Искать в цикле и выйти после прохода за листовой узел
while !cur.nil?
# Целевой узел находится в правом поддереве cur
if cur.val < num
cur = cur.right
# Целевой узел находится в левом поддереве cur
elsif cur.val > num
cur = cur.left
# Найти целевой узел и выйти из цикла
else
break
end
end
cur
end
### Вставка узла ### ### Вставка узла ###
def insert(num) def insert(num)
# Если дерево пусто, инициализировать корневой узел # Если дерево пусто, инициализировать корневой узел
@@ -1600,82 +1535,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="binary_search_tree.rb" ```ruby title="binary_search_tree.rb"
=begin
File: binary_search_tree.rb
Created Time: 2024-04-18
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
require_relative '../utils/tree_node'
require_relative '../utils/print_util'
# ## Двоичное дерево поиска ###
class BinarySearchTree
# ## Конструктор ###
def initialize
# Инициализировать пустое дерево
@root = nil
end
# ## Получение корневого узла двоичного дерева ###
def get_root
@root
end
# ## Поиск узла ###
def search(num)
cur = @root
# Искать в цикле и выйти после прохода за листовой узел
while !cur.nil?
# Целевой узел находится в правом поддереве cur
if cur.val < num
cur = cur.right
# Целевой узел находится в левом поддереве cur
elsif cur.val > num
cur = cur.left
# Найти целевой узел и выйти из цикла
else
break
end
end
cur
end
# ## Вставка узла ###
def insert(num)
# Если дерево пусто, инициализировать корневой узел
if @root.nil?
@root = TreeNode.new(num)
return
end
# Искать в цикле и выйти после прохода за листовой узел
cur, pre = @root, nil
while !cur.nil?
# Найти повторяющийся узел и сразу вернуть
return if cur.val == num
pre = cur
# Позиция вставки находится в правом поддереве cur
if cur.val < num
cur = cur.right
# Позиция вставки находится в левом поддереве cur
else
cur = cur.left
end
end
# Вставка узла
node = TreeNode.new(num)
if pre.val < num
pre.right = node
else
pre.left = node
end
end
### Удаление узла ### ### Удаление узла ###
def remove(num) def remove(num)
# Если дерево пусто, сразу вернуть # Если дерево пусто, сразу вернуть
@@ -318,15 +318,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="binary_tree_bfs.rb" ```ruby title="binary_tree_bfs.rb"
=begin
File: binary_tree_bfs.rb
Created Time: 2024-04-18
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
require_relative '../utils/tree_node'
require_relative '../utils/print_util'
### Обход в ширину ### ### Обход в ширину ###
def level_order(root) def level_order(root)
# Инициализировать очередь и добавить корневой узел # Инициализировать очередь и добавить корневой узел
@@ -797,63 +788,6 @@ comments: true
=== "Ruby" === "Ruby"
```ruby title="binary_tree_dfs.rb" ```ruby title="binary_tree_dfs.rb"
=begin
File: binary_tree_dfs.rb
Created Time: 2024-04-18
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
require_relative '../utils/tree_node'
require_relative '../utils/print_util'
# ## Предварительный обход ###
def pre_order(root)
return if root.nil?
# Порядок обхода: корень -> левое поддерево -> правое поддерево
$res << root.val
pre_order(root.left)
pre_order(root.right)
end
=begin
File: binary_tree_dfs.rb
Created Time: 2024-04-18
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
require_relative '../utils/tree_node'
require_relative '../utils/print_util'
# ## Предварительный обход ###
def pre_order(root)
return if root.nil?
# Порядок обхода: корень -> левое поддерево -> правое поддерево
$res << root.val
pre_order(root.left)
pre_order(root.right)
end
# ## Симметричный обход ###
def in_order(root)
return if root.nil?
# Порядок обхода: левое поддерево -> корень -> правое поддерево
in_order(root.left)
$res << root.val
in_order(root.right)
end
=begin
File: binary_tree_dfs.rb
Created Time: 2024-04-18
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
require_relative '../utils/tree_node'
require_relative '../utils/print_util'
### Предварительный обход ### ### Предварительный обход ###
def pre_order(root) def pre_order(root)
return if root.nil? return if root.nil?