-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path33-SearchinRotatedSortedArray.go
More file actions
139 lines (125 loc) · 4.1 KB
/
33-SearchinRotatedSortedArray.go
File metadata and controls
139 lines (125 loc) · 4.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
package main
// 33. Search in Rotated Sorted Array
// There is an integer array nums sorted in ascending order (with distinct values).
// Prior to being passed to your function, nums is possibly rotated at an unknown pivot index k (1 <= k < nums.length) such
// that the resulting array is [nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]] (0-indexed).
// For example, [0,1,2,4,5,6,7] might be rotated at pivot index 3 and become [4,5,6,7,0,1,2].
// Given the array nums after the possible rotation and an integer target,
// return the index of target if it is in nums, or -1 if it is not in nums.
// You must write an algorithm with O(log n) runtime complexity.
// Example 1:
// Input: nums = [4,5,6,7,0,1,2], target = 0
// Output: 4
// Example 2:
// Input: nums = [4,5,6,7,0,1,2], target = 3
// Output: -1
// Example 3:
// Input: nums = [1], target = 0
// Output: -1
// Constraints:
// 1 <= nums.length <= 5000
// -10^4 <= nums[i] <= 10^4
// All values of nums are unique.
// nums is an ascending array that is possibly rotated.
// -10^4 <= target <= 10^4
import "fmt"
func search(nums []int, target int) int {
if len(nums) == 0 {
return -1
}
low, high := 0, len(nums)-1
for low <= high {
mid := low + (high-low)>>1
if nums[mid] == target {
return mid
} else if nums[mid] > nums[low] { // 在数值大的一部分区间里
if nums[low] <= target && target < nums[mid] {
high = mid - 1
} else {
low = mid + 1
}
} else if nums[mid] < nums[high] { // 在数值小的一部分区间里
if nums[mid] < target && target <= nums[high] {
low = mid + 1
} else {
high = mid - 1
}
} else {
if nums[low] == nums[mid] {
low++
}
if nums[high] == nums[mid] {
high--
}
}
}
return -1
}
// best solution
func search1(nums []int, target int) int {
if len(nums) == 0 {
return -1
}
l, r := 0, len(nums) - 1
for l < r {
mid := l + (r - l) / 2
if nums[mid] > nums[r] { // 先找到中的点
l = mid + 1
} else {
r = mid
}
}
//fmt.Printf("l = %v\n",l) // 找到了 两段数组的中间
rot := l
l, r = 0, len(nums) - 1
if nums[rot] <= target && target <= nums[r] { // 确定值在哪段数组上
l = rot
} else {
r = rot - 1
}
for l <= r {
mid := l + (r - l) / 2
if nums[mid] == target {
return mid
} else if nums[mid] < target {
l = mid + 1
} else {
r = mid - 1
}
}
return -1
}
func search2(nums []int, target int) int {
l, r := 0,len(nums)-1
for l <= r {
mid := (l + r)/2
if nums[mid] == target {
return mid
}
if nums[0] <= nums[mid] {
if nums[0] <= target && target < nums[mid] {
r = mid -1
} else {
l = mid + 1
}
} else {
if nums[mid] < target && target <= nums[len(nums)-1] {
l = mid + 1
} else {
r = mid - 1
}
}
}
return -1
}
func main() {
fmt.Printf("search([]int{4,5,6,7,0,1,2},0) = %v\n",search([]int{4,5,6,7,0,1,2},0)) // 4
fmt.Printf("search([]int{4,5,6,7,0,1,2},3) = %v\n",search([]int{4,5,6,7,0,1,2},3)) // -1
fmt.Printf("search([]int{1},0) = %v\n",search([]int{1},0)) // -1
fmt.Printf("search1([]int{4,5,6,7,0,1,2},0) = %v\n",search1([]int{4,5,6,7,0,1,2},0)) //4
fmt.Printf("search1([]int{4,5,6,7,0,1,2},3) = %v\n",search1([]int{4,5,6,7,0,1,2},3)) // -1
fmt.Printf("search1([]int{1},0) = %v\n",search1([]int{1},0)) // -1
fmt.Printf("search2([]int{4,5,6,7,0,1,2},0) = %v\n",search2([]int{4,5,6,7,0,1,2},0)) //4
fmt.Printf("search2([]int{4,5,6,7,0,1,2},3) = %v\n",search2([]int{4,5,6,7,0,1,2},3)) // -1
fmt.Printf("search2([]int{1},0) = %v\n",search2([]int{1},0)) // -1
}