forked from krahets/hello-algo
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add ruby code - chapter "divide and conquer" (krahets#1361)
- Loading branch information
1 parent
063a41f
commit 9e569cf
Showing
3 changed files
with
143 additions
and
0 deletions.
There are no files selected for viewing
42 changes: 42 additions & 0 deletions
42
codes/ruby/chapter_divide_and_conquer/binary_search_recur.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
=begin | ||
File: binary_search_recur.rb | ||
Created Time: 2024-05-13 | ||
Author: Xuan Khoa Tu Nguyen ([email protected]) | ||
=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 | ||
|
||
### 二分查找 ### | ||
def binary_search(nums, target) | ||
n = nums.length | ||
# 求解问题 f(0, n-1) | ||
dfs(nums, target, 0, n - 1) | ||
end | ||
|
||
### Driver Code ### | ||
if __FILE__ == $0 | ||
target = 6 | ||
nums = [1, 3, 6, 8, 12, 15, 23, 26, 31, 35] | ||
|
||
# 二分查找(双闭区间) | ||
index = binary_search(nums, target) | ||
puts "目标元素 6 的索引 = #{index}" | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
=begin | ||
File: build_tree.rb | ||
Created Time: 2024-05-13 | ||
Author: Xuan Khoa Tu Nguyen ([email protected]) | ||
=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 | ||
|
||
### 构建二叉树 ### | ||
def build_tree(preorder, inorder) | ||
# 初始化哈希表,存储 inorder 元素到索引的映射 | ||
inorder_map = {} | ||
inorder.each_with_index { |val, i| inorder_map[val] = i } | ||
dfs(preorder, inorder_map, 0, 0, inorder.length - 1) | ||
end | ||
|
||
### Driver Code ### | ||
if __FILE__ == $0 | ||
preorder = [3, 9, 2, 1, 7] | ||
inorder = [9, 3, 1, 2, 7] | ||
puts "前序遍历 = #{preorder}" | ||
puts "中序遍历 = #{inorder}" | ||
|
||
root = build_tree(preorder, inorder) | ||
puts "构建的二叉树为:" | ||
print_tree(root) | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
=begin | ||
File: hanota.rb | ||
Created Time: 2024-05-13 | ||
Author: Xuan Khoa Tu Nguyen ([email protected]) | ||
=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) :将 src 顶部 i-1 个圆盘借助 tar 移到 buf | ||
dfs(i - 1, src, tar, buf) | ||
# 子问题 f(1) :将 src 剩余一个圆盘移到 tar | ||
move(src, tar) | ||
# 子问题 f(i-1) :将 buf 顶部 i-1 个圆盘借助 src 移到 tar | ||
dfs(i - 1, buf, src, tar) | ||
end | ||
|
||
### 求解汉诺塔问题 ### | ||
def solve_hanota(_A, _B, _C) | ||
n = _A.length | ||
# 将 A 顶部 n 个圆盘借助 B 移到 C | ||
dfs(n, _A, _B, _C) | ||
end | ||
|
||
### Driver Code ### | ||
if __FILE__ == $0 | ||
# 列表尾部是柱子顶部 | ||
A = [5, 4, 3, 2, 1] | ||
B = [] | ||
C = [] | ||
puts "初始状态下:" | ||
puts "A = #{A}" | ||
puts "B = #{B}" | ||
puts "C = #{C}" | ||
|
||
solve_hanota(A, B, C) | ||
|
||
puts "圆盘移动完成后:" | ||
puts "A = #{A}" | ||
puts "B = #{B}" | ||
puts "C = #{C}" | ||
end |