旋转数组的最小数字(六)

题目描述:

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组 ​​{3,4,5,1,2}​​​ 为 ​​{1,2,3,4,5}​​​ 的一个旋转,该数组的最小值为 ​​1​​​。 NOTE:给出的所有元素都大于 ​​0​​​,若数组大小为 ​​0​​​,请返回 ​​0​​。

代码(已在牛客上 AC)

如果数组中没有重复数字, 那就好办了. 使用二分查找搜索第一个小于 ​​nums[0]​​ 的方法. 但是如果数组中存在重复数字, 那么旋转之后可能是如下这样:

2 3 3 4 1 2 2 2

由于 ​​2​​​ 的重复数字较多, 旋转之后, 如果直接使用二分查找, 就会找错. 因此我下面代码中, 先使用 ​​while (r >= 0 && rotateArray[r] == rotateArray[0]) r --;​​​ 从右边开始找到第一个不等于 ​​rotateArray[0]​​​ 的数的索引, 那么再用二分查找搜索 ​​rotateArray[0....r]​​ 范围内的元素.

class Solution {
private:
int search(vector<int> &nums, int l, int r) {
if (nums.empty()) return 0;
int end = r;
while (l <= r) {
int mid = l + (r - l) / 2;
if (nums[0] <= nums[mid]) l = mid + 1;
else r = mid - 1;
}
return l > end ? nums[0] : nums[l];
}
public:
int minNumberInRotateArray(vector<int> rotateArray) {
if (rotateArray.empty()) return 0;
int r = rotateArray.size() - 1;
while (r >= 0 && rotateArray[r] == rotateArray[0]) r --;
return search(rotateArray, 0, r);
}
};