每日leetcode-154

  1. 寻找旋转排序数组中的最小值 II

假设按照升序排序的数组在预先未知的某个点上进行了旋转。

( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。

请找出其中最小的元素。

注意数组中可能存在重复的元素。

示例 1:

输入: [1,3,5]
输出: 1

示例 2:

输入: [2,2,2,0,1]
输出: 0

解答

因为有可能左、右、中间都相等,所以需要两边分别二分看

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
class Solution {
public:
int myMin(vector<int>& nums, int left, int right) {
if (left >= right || nums[left] < nums[right]) {
return nums[left];
}
int mid = (left + right) / 2;
if (nums[left] == nums[right]) {
if (nums[mid] < nums[left]) {
return myMin(nums, left, mid);
}
if (nums[mid] > nums[left]) {
return myMin(nums, mid + 1, right);
}
return min(myMin(nums, left, mid - 1), myMin(nums, mid + 1, right));
}
// left > right
else {
if (nums[mid] < nums[right]) {
return myMin(nums, left, mid);
}
if (nums[mid] > nums[right]) {
return myMin(nums, mid + 1, right);
}
// nums[mid] == nums[right]
return min(myMin(nums, left, mid - 1), myMin(nums, mid + 1, right));
}
}

int findMin(vector<int>& nums) {
return myMin(nums, 0, nums.size() - 1);
}
};

可以优化一下合并中间的对left right大小的判断:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Solution {
public:
int myMin(vector<int>& nums, int left, int right) {
if (left >= right || nums[left] < nums[right]) {
return nums[left];
}
int mid = (left + right) / 2;
if (nums[mid] < nums[right]) {
return myMin(nums, left, mid);
}
if (nums[mid] > nums[right]) {
return myMin(nums, mid + 1, right);
}
// nums[mid] == nums[right]
return min(myMin(nums, left, mid - 1), myMin(nums, mid + 1, right));
}

int findMin(vector<int>& nums) {
return myMin(nums, 0, nums.size() - 1);
}
};

非递归的做法

(题解里面提到的)在left、right、mid对应的都相等的时候,不是分别算求min,而是将r–

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Solution {
public:
int findMin(vector<int>& nums) {
int left = 0, right = nums.size() - 1;
while (true) {
if (left >= right || nums[left] < nums[right]) {
return nums[left];
}
int mid = (left + right) / 2;
if (nums[mid] < nums[right]) {
right = mid;
}
else if (nums[mid] > nums[right]) {
left = mid + 1;
}
else {
right--;
}
}
}
};