题目内容:
Follow up for “Find Minimum in Rotated Sorted Array”:
What if duplicates are allowed?Would this affect the run-time complexity? How and why?
Suppose a sorted array is rotated at some pivot unknown to you beforehand.
(i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2).
Find the minimum element.
The array may contain duplicates.
Subscribe to see which companies asked this question
思路:
和上一题一样,使用二分查找的变体即可。但是考虑重复元素带来的特殊情况,如:[1,2,2,2,0,1,1],[1,0,1,1,1]。
两种处理方式:
1. 遇到首尾相同,在start和mid,mid和end之间同时使用变体二分查找,返回这两个查找的最小值之间的最小值
2. 在迭代过程中发现mid和start,end都相等,则只能使用顺序查找。
代码:
递归实现,处理方法1:
class Solution {
public:
int findMin(vector<int>& nums) {
if(nums.size() == 1)
return nums[0];
return findMin(nums, 0, nums.size()-1);
}
// use start to point to the former part
// use end to point to the later part
// when start is next to end, end is the min number
int findMin(vector<int> &nums, int start, int end) {
if(nums[start] < nums[end])
return nums[start];
if(start + 1 == end)
return nums[end];
int mid((start+end)/2);
if(nums[mid] > nums[start])
return findMin(nums, mid, end);
else if(nums[mid] < nums[start])
return findMin(nums, start, mid);
else
// linear search can also work
return min(findMin(nums, mid, end), findMin(nums, start, mid));
}
};
迭代实现,处理方法二:
class Solution {
public:
int findMin(vector<int>& nums) {
if(nums.size() == 1)
return nums[0];
return findMin(nums, 0, nums.size()-1);
}
// use start to point to the former part
// use end to point to the later part
// when start is next to end, end is the min number
int findMin(vector<int> &nums, int start, int end) {
if(nums[start] < nums[end])
return nums[start];
while(start + 1 < end) {
int mid((start+end)>>1);
if(nums[mid] == nums[start] && nums[mid] == nums[end]) {
return MinInOrder(nums, start, end);
}
if(nums[mid] >= nums[start])
start = mid;
else
end = mid;
}
return nums[end];
}
int MinInOrder(vector<int> &nums, int start, int end) {
int result(nums[start]);
for(int i = start; i <= end; ++i)
result = result < nums[i] ? result : nums[i];
return result;
}
};