Skip to content

Commit 0cfb2a1

Browse files
committed
704. Binary Search
1 parent 448504e commit 0cfb2a1

File tree

4 files changed

+333
-0
lines changed

4 files changed

+333
-0
lines changed
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
# [704. Binary Search](https://leetcode.com/problems/binary-search/)
2+
3+
## 題目
4+
5+
Given an array of integers nums which is sorted in ascending order, and an integer target, write a function to search target in nums. If target exists, then return its index. Otherwise, return -1.
6+
7+
You must write an algorithm with O(log n) runtime complexity.
8+
9+
10+
11+
Example 1:
12+
13+
```
14+
Input: nums = [-1,0,3,5,9,12], target = 9
15+
Output: 4
16+
Explanation: 9 exists in nums and its index is 4
17+
```
18+
19+
Example 2:
20+
21+
```
22+
Input: nums = [-1,0,3,5,9,12], target = 2
23+
Output: -1
24+
Explanation: 2 does not exist in nums so return -1
25+
```
26+
27+
Constraints:
28+
29+
* 1 <= nums.length <= 104
30+
* -104 < nums[i], target < 104
31+
* All the integers in nums are unique.
32+
* nums is sorted in ascending order.
33+
34+
## 題目大意
35+
給一個已排序過後的array, 找出target所在index
36+
若未找到回傳 -1
37+
38+
## 解題思路
39+
40+
41+
## 提示:
42+
43+
44+
## 來源
45+
* https://leetcode.com/problems/binary-search/
46+
47+
## 解答
48+
https://github.com/kimi0230/LeetcodeGolang/blob/master/Leetcode/0704.Binary-Search/main.go
49+
50+
```go
51+
package binarysearch
52+
53+
import "sort"
54+
55+
func Search(nums []int, target int) int {
56+
lenght := len(nums)
57+
if lenght <= 0 {
58+
return -1
59+
}
60+
left, right := 0, lenght-1
61+
62+
for left <= right {
63+
mid := (right-left)/2 + left
64+
if nums[mid] == target {
65+
return mid
66+
} else if nums[mid] < target {
67+
// 找右邊
68+
left = mid + 1
69+
} else if nums[mid] > target {
70+
// 找左邊
71+
right = mid - 1
72+
}
73+
}
74+
// 都沒找到
75+
return -1
76+
}
77+
78+
func Search2(nums []int, target int) int {
79+
lenght := len(nums)
80+
if lenght <= 0 {
81+
return -1
82+
}
83+
left, right := 0, lenght-1
84+
85+
for left <= right {
86+
// 除以2
87+
// mid := left + (right-left)>>1
88+
mid := int(uint(right+left) >> 1)
89+
if nums[mid] == target {
90+
return mid
91+
} else if nums[mid] < target {
92+
// 找右邊
93+
left = mid + 1
94+
} else if nums[mid] > target {
95+
// 找左邊
96+
right = mid - 1
97+
}
98+
}
99+
// 都沒找到
100+
return -1
101+
}
102+
103+
// 內建sort
104+
func BinarySearch(nums []int, target int) int {
105+
length := len(nums)
106+
107+
index := sort.Search(length, func(i int) bool {
108+
return nums[i] >= target
109+
})
110+
111+
if index < length && nums[index] == target {
112+
return index
113+
} else {
114+
return -1
115+
}
116+
}
117+
118+
// 使用遞迴
119+
func BinarySearchRecur(nums []int, target int) (index int) {
120+
return BinarySearchRecursively(nums, target, 0, len(nums)-1)
121+
}
122+
123+
func BinarySearchRecursively(nums []int, target int, start int, end int) int {
124+
if end < start {
125+
return -1
126+
}
127+
128+
middle := int(uint(end+start) >> 1)
129+
130+
if nums[middle] == target {
131+
return middle
132+
} else if target > nums[middle] {
133+
return BinarySearchRecursively(nums, target, middle+1, end)
134+
} else {
135+
return BinarySearchRecursively(nums, target, start, middle-1)
136+
}
137+
}
138+
139+
```
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
package binarysearch
2+
3+
import "sort"
4+
5+
func Search(nums []int, target int) int {
6+
lenght := len(nums)
7+
if lenght <= 0 {
8+
return -1
9+
}
10+
left, right := 0, lenght-1
11+
12+
for left <= right {
13+
mid := (right-left)/2 + left
14+
if nums[mid] == target {
15+
return mid
16+
} else if nums[mid] < target {
17+
// 找右邊
18+
left = mid + 1
19+
} else if nums[mid] > target {
20+
// 找左邊
21+
right = mid - 1
22+
}
23+
}
24+
// 都沒找到
25+
return -1
26+
}
27+
28+
func Search2(nums []int, target int) int {
29+
lenght := len(nums)
30+
if lenght <= 0 {
31+
return -1
32+
}
33+
left, right := 0, lenght-1
34+
35+
for left <= right {
36+
// 除以2
37+
// mid := left + (right-left)>>1
38+
mid := int(uint(right+left) >> 1)
39+
if nums[mid] == target {
40+
return mid
41+
} else if nums[mid] < target {
42+
// 找右邊
43+
left = mid + 1
44+
} else if nums[mid] > target {
45+
// 找左邊
46+
right = mid - 1
47+
}
48+
}
49+
// 都沒找到
50+
return -1
51+
}
52+
53+
// 內建sort
54+
func BinarySearch(nums []int, target int) int {
55+
length := len(nums)
56+
57+
index := sort.Search(length, func(i int) bool {
58+
return nums[i] >= target
59+
})
60+
61+
if index < length && nums[index] == target {
62+
return index
63+
} else {
64+
return -1
65+
}
66+
}
67+
68+
// 使用遞迴
69+
func BinarySearchRecur(nums []int, target int) (index int) {
70+
return BinarySearchRecursively(nums, target, 0, len(nums)-1)
71+
}
72+
73+
func BinarySearchRecursively(nums []int, target int, start int, end int) int {
74+
if end < start {
75+
return -1
76+
}
77+
78+
middle := int(uint(end+start) >> 1)
79+
80+
if nums[middle] == target {
81+
return middle
82+
} else if target > nums[middle] {
83+
return BinarySearchRecursively(nums, target, middle+1, end)
84+
} else {
85+
return BinarySearchRecursively(nums, target, start, middle-1)
86+
}
87+
}
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
package binarysearch
2+
3+
import "testing"
4+
5+
var tests = []struct {
6+
arg1 []int
7+
arg2 int
8+
want int
9+
}{
10+
{
11+
[]int{-1, 0, 3, 5, 9, 12},
12+
9,
13+
4,
14+
},
15+
{
16+
[]int{-1, 0, 3, 5, 9, 12},
17+
2,
18+
-1,
19+
},
20+
{
21+
[]int{-1, 0, 3, 5, 9, 12},
22+
13,
23+
-1,
24+
},
25+
}
26+
27+
func TestSearch(t *testing.T) {
28+
for _, tt := range tests {
29+
if got := Search(tt.arg1, tt.arg2); got != tt.want {
30+
t.Errorf("got = %v, want = %v", got, tt.want)
31+
}
32+
}
33+
}
34+
35+
func TestSearch2(t *testing.T) {
36+
for _, tt := range tests {
37+
if got := Search2(tt.arg1, tt.arg2); got != tt.want {
38+
t.Errorf("got = %v, want = %v", got, tt.want)
39+
}
40+
}
41+
}
42+
43+
func TestBinarySearch(t *testing.T) {
44+
for _, tt := range tests {
45+
if got := BinarySearch(tt.arg1, tt.arg2); got != tt.want {
46+
t.Errorf("got = %v, want = %v", got, tt.want)
47+
}
48+
}
49+
}
50+
51+
func TestBinarySearchRecur(t *testing.T) {
52+
for _, tt := range tests {
53+
if got := BinarySearchRecur(tt.arg1, tt.arg2); got != tt.want {
54+
t.Errorf("got = %v, want = %v", got, tt.want)
55+
}
56+
}
57+
}
58+
59+
func BenchmarkSearch(b *testing.B) {
60+
b.ResetTimer()
61+
for i := 0; i < b.N; i++ {
62+
Search(tests[0].arg1, tests[0].arg2)
63+
}
64+
}
65+
func BenchmarkSearch2(b *testing.B) {
66+
b.ResetTimer()
67+
for i := 0; i < b.N; i++ {
68+
Search2(tests[0].arg1, tests[0].arg2)
69+
}
70+
}
71+
72+
func BenchmarkBinarySearch(b *testing.B) {
73+
b.ResetTimer()
74+
for i := 0; i < b.N; i++ {
75+
BinarySearch(tests[0].arg1, tests[0].arg2)
76+
}
77+
}
78+
79+
func BenchmarkBinarySearchRecur(b *testing.B) {
80+
b.ResetTimer()
81+
for i := 0; i < b.N; i++ {
82+
BinarySearchRecur(tests[0].arg1, tests[0].arg2)
83+
}
84+
}
85+
86+
/*
87+
go test -benchmem -run=none LeetcodeGolang/Leetcode/0704.Binary-Search -bench=.
88+
goos: darwin
89+
goarch: amd64
90+
pkg: LeetcodeGolang/Leetcode/0704.Binary-Search
91+
cpu: Intel(R) Core(TM) i5-6400 CPU @ 2.70GHz
92+
BenchmarkSearch-4 365892498 3.483 ns/op 0 B/op 0 allocs/op
93+
BenchmarkSearch2-4 405742570 2.734 ns/op 0 B/op 0 allocs/op
94+
BenchmarkBinarySearch-4 81949826 13.15 ns/op 0 B/op 0 allocs/op
95+
BenchmarkBinarySearchRecur-4 253851086 4.588 ns/op 0 B/op 0 allocs/op
96+
*/

README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
- [Bit Manipulation](#bit-manipulation)
1919
- [Union Find](#union-find)
2020
- [Breadth First Search](#breadth-first-search)
21+
- [Binary Search](#binary-search)
2122
- [GeeksforGeeks Content](#geeksforgeeks-content)
2223
- [Codility Content](#codility-content)
2324
- [Reference](#reference)
@@ -208,6 +209,16 @@ int BFS(Node start, Node targe){
208209
| 0310 | [Minimum Height Trees](https://leetcode.com/problems/minimum-height-trees/) | [Go](https://github.com/kimi0230/LeetcodeGolang/tree/master/Leetcode/0310.Minimum-Height-Trees) | Medium | | | Breadth First Search |
209210
| 0752 | [752. Open the Lock](https://leetcode.com/problems/open-the-lock/) | [Go](https://github.com/kimi0230/LeetcodeGolang/tree/master/Leetcode/0752.Open-the-Lock) | Medium | | | Breadth First Search |
210211

212+
---
213+
#### Binary Search
214+
分析二分搜尋技巧: 不要出現 **else**, 而是把所有情況用 **else if** 寫清楚.
215+
計算 mid 時需要防止溢出
216+
217+
| No. | Title | Solution | Difficulty | Time | Space | Topic |
218+
|-----|:-----:|:--------:|------------|------|-------|-------|
219+
| 0704 | [704. Binary Search](https://leetcode.com/problems/binary-search/) | [Go](https://github.com/kimi0230/LeetcodeGolang/tree/master/Leetcode/0704.Binary-Search) | Easy | 最差:O(long n)<br> 最佳O(1)剛好在中間 | 迭代: O(1) <br/> 遞迴O(log n) | Binary Search |
220+
221+
211222
---
212223

213224
## [GeeksforGeeks](https://www.geeksforgeeks.org/) Content

0 commit comments

Comments
 (0)