Skip to content

Commit e245742

Browse files
committed
feat: add solutions to lcof problem: No.11
1 parent 0ccff44 commit e245742

File tree

4 files changed

+237
-71
lines changed

4 files changed

+237
-71
lines changed

lcof/面试题11. 旋转数组的最小数字/README.md

Lines changed: 211 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,22 @@
2424

2525
## 解法
2626

27+
**方法一:二分查找**
28+
29+
二分查找的变种,需要考虑重复元素的情况。
30+
31+
我们定义两个指针 $l$ 和 $r$ 分别指向数组的左右两端,每次取中间元素 `numbers[mid]` 与右端元素 `numbers[r]` 比较,有以下三种情况:
32+
33+
- `numbers[mid] > numbers[r]`:中间元素一定不是最小值,因此 $l = mid + 1$;
34+
- `numbers[mid] < numbers[r]`:中间元素可能是最小值,因此 $r = mid$;
35+
- `numbers[mid] == numbers[r]`:中间元素一定不是最小值,因此 $r = r - 1$。
36+
37+
循环结束时,指针 $l$ 和 $r$ 指向同一个元素,即为最小值。
38+
39+
时间复杂度 $(\log n)$,空间复杂度 $O(1)$。其中 $n$ 为数组长度。
40+
41+
注意,我们也可以每次取中间元素 `numbers[mid]` 与左端元素 `numbers[l]` 比较,但需要考虑当前 $[l,..r]$ 区间内的元素是否已经有序,即是否满足 `numbers[l] < numbers[r]`,如果满足,直接返回 `numbers[l]` 即可。其它情况与上述方法类似。
42+
2743
<!-- tabs:start -->
2844

2945
### **Python3**
@@ -43,6 +59,23 @@ class Solution:
4359
return numbers[l]
4460
```
4561

62+
```python
63+
class Solution:
64+
def minArray(self, numbers: List[int]) -> int:
65+
l, r = 0, len(numbers) - 1
66+
while l < r:
67+
if numbers[l] < numbers[r]:
68+
return numbers[l]
69+
mid = (l + r) >> 1
70+
if numbers[mid] > numbers[l]:
71+
l = mid + 1
72+
elif numbers[mid] < numbers[l]:
73+
r = mid
74+
else:
75+
l += 1
76+
return numbers[l]
77+
```
78+
4679
### **Java**
4780

4881
```java
@@ -64,6 +97,112 @@ class Solution {
6497
}
6598
```
6699

100+
```java
101+
class Solution {
102+
public int minArray(int[] numbers) {
103+
int l = 0, r = numbers.length - 1;
104+
while (l < r) {
105+
if (numbers[l] < numbers[r]) {
106+
break;
107+
}
108+
int m = (l + r) >>> 1;
109+
if (numbers[m] > numbers[l]) {
110+
l = m + 1;
111+
} else if (numbers[m] < numbers[l]) {
112+
r = m;
113+
} else {
114+
++l;
115+
}
116+
}
117+
return numbers[l];
118+
}
119+
}
120+
```
121+
122+
### **C++**
123+
124+
```cpp
125+
class Solution {
126+
public:
127+
int minArray(vector<int>& numbers) {
128+
int l = 0, r = numbers.size() - 1;
129+
while (l < r) {
130+
int mid = (l + r) >> 1;
131+
if (numbers[mid] > numbers[r]) {
132+
l = mid + 1;
133+
} else if (numbers[mid] < numbers[r]) {
134+
r = mid;
135+
} else {
136+
--r;
137+
}
138+
}
139+
return numbers[l];
140+
}
141+
};
142+
```
143+
144+
```cpp
145+
class Solution {
146+
public:
147+
int minArray(vector<int>& numbers) {
148+
int l = 0, r = numbers.size() - 1;
149+
while (l < r) {
150+
if (numbers[l] < numbers[r]) {
151+
break;
152+
}
153+
int mid = (l + r) >> 1;
154+
if (numbers[mid] > numbers[l]) {
155+
l = mid + 1;
156+
} else if (numbers[mid] < numbers[l]) {
157+
r = mid;
158+
} else {
159+
++l;
160+
}
161+
}
162+
return numbers[l];
163+
}
164+
};
165+
```
166+
167+
### **Go**
168+
169+
```go
170+
func minArray(numbers []int) int {
171+
l, r := 0, len(numbers)-1
172+
for l < r {
173+
mid := (l + r) >> 1
174+
if numbers[mid] > numbers[r] {
175+
l = mid + 1
176+
} else if numbers[mid] < numbers[r] {
177+
r = mid
178+
} else {
179+
r--
180+
}
181+
}
182+
return numbers[l]
183+
}
184+
```
185+
186+
```go
187+
func minArray(numbers []int) int {
188+
l, r := 0, len(numbers)-1
189+
for l < r {
190+
if numbers[l] < numbers[r] {
191+
break
192+
}
193+
mid := (l + r) >> 1
194+
if numbers[mid] > numbers[l] {
195+
l = mid + 1
196+
} else if numbers[mid] < numbers[l] {
197+
r = mid
198+
} else {
199+
l++
200+
}
201+
}
202+
return numbers[l]
203+
}
204+
```
205+
67206
### **JavaScript**
68207

69208
```js
@@ -88,44 +227,28 @@ var minArray = function (numbers) {
88227
};
89228
```
90229

91-
### **Go**
92-
93-
```go
94-
func minArray(nums []int) int {
95-
l, r := 0, len(nums)-1
96-
for l < r {
97-
mid := l + (r-l)>>1
98-
if nums[mid] > nums[r] {
99-
l = mid + 1
100-
} else if nums[mid] < nums[r] {
101-
r = mid // r 本身不需要被排除
102-
} else {
103-
r--
104-
}
105-
}
106-
return nums[l]
107-
}
108-
```
109-
110-
### **C++**
111-
112-
```cpp
113-
class Solution {
114-
public:
115-
int minArray(vector<int>& numbers) {
116-
int left = 0, right = numbers.size() - 1;
117-
while (left + 1 < right) {
118-
int mid = left + (right - left) / 2;
119-
if (numbers[mid] > numbers[right]) {
120-
left = mid;
121-
} else if (numbers[mid] < numbers[right]) {
122-
right = mid;
123-
} else {
124-
--right;
125-
}
230+
```js
231+
/**
232+
* @param {number[]} numbers
233+
* @return {number}
234+
*/
235+
var minArray = function (numbers) {
236+
let l = 0,
237+
r = numbers.length - 1;
238+
while (l < r) {
239+
if (numbers[l] < numbers[r]) {
240+
break;
241+
}
242+
let m = (l + r) >>> 1;
243+
if (numbers[m] > numbers[l]) {
244+
l = m + 1;
245+
} else if (numbers[m] < numbers[l]) {
246+
r = m;
247+
} else {
248+
++l;
126249
}
127-
return min(numbers[left], numbers[right]);
128250
}
251+
return numbers[l];
129252
};
130253
```
131254

@@ -149,23 +272,66 @@ impl Solution {
149272
}
150273
```
151274

275+
```rust
276+
impl Solution {
277+
pub fn min_array(numbers: Vec<i32>) -> i32 {
278+
let mut l = 0;
279+
let mut r = numbers.len() - 1;
280+
while l < r {
281+
if numbers[l] < numbers[r] {
282+
break;
283+
}
284+
let mid = l + r >> 1;
285+
match numbers[mid].cmp(&numbers[l]) {
286+
std::cmp::Ordering::Less => r = mid,
287+
std::cmp::Ordering::Equal => l += 1,
288+
std::cmp::Ordering::Greater => l = mid + 1,
289+
}
290+
}
291+
numbers[l]
292+
}
293+
}
294+
```
295+
152296
### **C#**
153297

154298
```cs
155299
public class Solution {
156300
public int MinArray(int[] numbers) {
157-
int left = 0, right = numbers.Length - 1, mid;
158-
while (left < right) {
159-
mid = (left + right) / 2;
160-
if (numbers[mid] > numbers[right]) {
161-
left = mid + 1;
162-
} else if (numbers[mid] < numbers[right]) {
163-
right = mid;
301+
int l = 0, r = numbers.Length - 1;
302+
while (l < r) {
303+
int m = (l + r) >> 1;
304+
if (numbers[m] > numbers[r]) {
305+
l = m + 1;
306+
} else if (numbers[m] < numbers[r]) {
307+
r = m;
164308
} else {
165-
right -= 1;
309+
--r;
166310
}
167311
}
168-
return numbers[left];
312+
return numbers[l];
313+
}
314+
}
315+
```
316+
317+
```cs
318+
public class Solution {
319+
public int MinArray(int[] numbers) {
320+
int l = 0, r = numbers.Length - 1;
321+
while (l < r) {
322+
if (numbers[l] < numbers[r]) {
323+
break;
324+
}
325+
int m = (l + r) >> 1;
326+
if (numbers[m] > numbers[l]) {
327+
l = m + 1;
328+
} else if (numbers[m] < numbers[l]) {
329+
r = m;
330+
} else {
331+
++l;
332+
}
333+
}
334+
return numbers[l];
169335
}
170336
}
171337
```
Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
class Solution {
22
public:
33
int minArray(vector<int>& numbers) {
4-
int left = 0, right = numbers.size() - 1;
5-
while (left + 1 < right) {
6-
int mid = left + (right - left) / 2;
7-
if (numbers[mid] > numbers[right]) {
8-
left = mid;
9-
} else if (numbers[mid] < numbers[right]) {
10-
right = mid;
4+
int l = 0, r = numbers.size() - 1;
5+
while (l < r) {
6+
int mid = (l + r) >> 1;
7+
if (numbers[mid] > numbers[r]) {
8+
l = mid + 1;
9+
} else if (numbers[mid] < numbers[r]) {
10+
r = mid;
1111
} else {
12-
--right;
12+
--r;
1313
}
1414
}
15-
return min(numbers[left], numbers[right]);
15+
return numbers[l];
1616
}
17-
};
17+
};
Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
public class Solution {
22
public int MinArray(int[] numbers) {
3-
int left = 0, right = numbers.Length - 1, mid;
4-
while (left < right) {
5-
mid = (left + right) / 2;
6-
if (numbers[mid] > numbers[right]) {
7-
left = mid + 1;
8-
} else if (numbers[mid] < numbers[right]) {
9-
right = mid;
3+
int l = 0, r = numbers.Length - 1;
4+
while (l < r) {
5+
int m = (l + r) >> 1;
6+
if (numbers[m] > numbers[r]) {
7+
l = m + 1;
8+
} else if (numbers[m] < numbers[r]) {
9+
r = m;
1010
} else {
11-
right -= 1;
11+
--r;
1212
}
1313
}
14-
return numbers[left];
14+
return numbers[l];
1515
}
1616
}
Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
func minArray(nums []int) int {
2-
l, r := 0, len(nums)-1
1+
func minArray(numbers []int) int {
2+
l, r := 0, len(numbers)-1
33
for l < r {
4-
mid := l + (r-l)>>1
5-
if nums[mid] > nums[r] {
4+
mid := (l + r) >> 1
5+
if numbers[mid] > numbers[r] {
66
l = mid + 1
7-
} else if nums[mid] < nums[r] {
8-
r = mid // r 本身不需要被排除
7+
} else if numbers[mid] < numbers[r] {
8+
r = mid
99
} else {
1010
r--
1111
}
1212
}
13-
return nums[l]
13+
return numbers[l]
1414
}

0 commit comments

Comments
 (0)