mirror of
https://github.com/krahets/hello-algo.git
synced 2024-12-25 15:36:29 +08:00
feat(go): support binary search & fix comments (#691)
This commit is contained in:
parent
1aa558bd2d
commit
628a274b50
4 changed files with 118 additions and 1 deletions
|
@ -23,7 +23,7 @@ func coinChangeIIDP(coins []int, amt int) int {
|
||||||
// 若超过背包容量,则不选硬币 i
|
// 若超过背包容量,则不选硬币 i
|
||||||
dp[i][a] = dp[i-1][a]
|
dp[i][a] = dp[i-1][a]
|
||||||
} else {
|
} else {
|
||||||
// 不选和选硬币 i 这两种方案的较小值
|
// 不选和选硬币 i 这两种方案之和
|
||||||
dp[i][a] = dp[i-1][a] + dp[i][a-coins[i-1]]
|
dp[i][a] = dp[i-1][a] + dp[i][a-coins[i-1]]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
31
codes/go/chapter_searching/binary_search_edge.go
Normal file
31
codes/go/chapter_searching/binary_search_edge.go
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
// File: binary_search_edge.go
|
||||||
|
// Created Time: 2023-08-23
|
||||||
|
// Author: Reanon (793584285@qq.com)
|
||||||
|
|
||||||
|
package chapter_searching
|
||||||
|
|
||||||
|
// 二分查找最左一个 target
|
||||||
|
func binarySearchLeftEdge(nums []int, target int) int {
|
||||||
|
// 等价于查找 target 的插入点
|
||||||
|
i := binarySearchInsertion(nums, target)
|
||||||
|
// 未找到 target ,返回 -1
|
||||||
|
if i == len(nums) || nums[i] != target {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
// 找到 target ,返回索引 i
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
|
||||||
|
// 二分查找最右一个 target
|
||||||
|
func binarySearchRightEdge(nums []int, target int) int {
|
||||||
|
// 转化为查找最左一个 target + 1
|
||||||
|
i := binarySearchInsertion(nums, target+1)
|
||||||
|
// j 指向最右一个 target ,i 指向首个大于 target 的元素
|
||||||
|
j := i - 1
|
||||||
|
// 未找到 target ,返回 -1
|
||||||
|
if j == -1 || nums[j] != target {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
// 找到 target ,返回索引 j
|
||||||
|
return j
|
||||||
|
}
|
49
codes/go/chapter_searching/binary_search_insertion.go
Normal file
49
codes/go/chapter_searching/binary_search_insertion.go
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
// File: binary_search_insertion.go
|
||||||
|
// Created Time: 2023-08-23
|
||||||
|
// Author: Reanon (793584285@qq.com)
|
||||||
|
|
||||||
|
package chapter_searching
|
||||||
|
|
||||||
|
// 二分查找插入点(无重复元素)
|
||||||
|
func binarySearchInsertionSimple(nums []int, target int) int {
|
||||||
|
// 初始化双闭区间 [0, n-1]
|
||||||
|
i, j := 0, len(nums)-1
|
||||||
|
for i <= j {
|
||||||
|
// 计算中点索引 m
|
||||||
|
m := i + (j-i)/2
|
||||||
|
if nums[m] < target {
|
||||||
|
// target 在区间 [m+1, j] 中
|
||||||
|
i = m + 1
|
||||||
|
} else if nums[m] > target {
|
||||||
|
// target 在区间 [i, m-1] 中
|
||||||
|
j = m - 1
|
||||||
|
} else {
|
||||||
|
// 找到 target ,返回插入点 m
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 未找到 target ,返回插入点 i
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
|
||||||
|
// 二分查找插入点(存在重复元素)
|
||||||
|
func binarySearchInsertion(nums []int, target int) int {
|
||||||
|
// 初始化双闭区间 [0, n-1]
|
||||||
|
i, j := 0, len(nums)-1
|
||||||
|
for i <= j {
|
||||||
|
// 计算中点索引 m
|
||||||
|
m := i + (j-i)/2
|
||||||
|
if nums[m] < target {
|
||||||
|
// target 在区间 [m+1, j] 中
|
||||||
|
i = m + 1
|
||||||
|
} else if nums[m] > target {
|
||||||
|
// target 在区间 [i, m-1] 中
|
||||||
|
j = m - 1
|
||||||
|
} else {
|
||||||
|
// 首个小于 target 的元素在区间 [i, m-1] 中
|
||||||
|
j = m - 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 返回插入点 i
|
||||||
|
return i
|
||||||
|
}
|
|
@ -22,3 +22,40 @@ func TestBinarySearch(t *testing.T) {
|
||||||
t.Errorf("目标元素 6 的索引 = %d, 应该为 %d", actual, expected)
|
t.Errorf("目标元素 6 的索引 = %d, 应该为 %d", actual, expected)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestBinarySearchEdge(t *testing.T) {
|
||||||
|
// 包含重复元素的数组
|
||||||
|
nums := []int{1, 3, 6, 8, 12, 15, 23, 26, 31, 35}
|
||||||
|
fmt.Println("\n数组 nums = ", nums)
|
||||||
|
|
||||||
|
// 二分查找左边界和右边界
|
||||||
|
for _, target := range []int{6, 7} {
|
||||||
|
index := binarySearchLeftEdge(nums, target)
|
||||||
|
fmt.Println("最左一个元素", target, "的索引为", index)
|
||||||
|
|
||||||
|
index = binarySearchRightEdge(nums, target)
|
||||||
|
fmt.Println("最右一个元素", target, "的索引为", index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBinarySearchInsertion(t *testing.T) {
|
||||||
|
// 无重复元素的数组
|
||||||
|
nums := []int{1, 3, 6, 8, 12, 15, 23, 26, 31, 35}
|
||||||
|
fmt.Println("数组 nums =", nums)
|
||||||
|
|
||||||
|
// 二分查找插入点
|
||||||
|
for _, target := range []int{6, 9} {
|
||||||
|
index := binarySearchInsertionSimple(nums, target)
|
||||||
|
fmt.Println("元素", target, "的插入点的索引为", index)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 包含重复元素的数组
|
||||||
|
nums = []int{1, 3, 6, 6, 6, 6, 6, 10, 12, 15}
|
||||||
|
fmt.Println("\n数组 nums =", nums)
|
||||||
|
|
||||||
|
// 二分查找插入点
|
||||||
|
for _, target := range []int{2, 6, 20} {
|
||||||
|
index := binarySearchInsertion(nums, target)
|
||||||
|
fmt.Println("元素", target, "的插入点的索引为", index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue