题目:
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.
题意:
依旧是有序数组翻转了,不过这次允许有相同的元素。
思路:
- 考虑到有相同元素,那么可能会出现比如 3,3,2,1,3,3;如果扫描到的middle的元素比end对应的元素小,说明middle是在后面的升序数组部分。如果middle的元素比end的大,说明middle处在前面的降序部分。但是如果middle的值跟end的一样大比如上面的例子,3可能是处于前面的降序部分,也可能处于后面的升序部分,所以这个时候无法判定下一步通过二分法该缩小的范围。把end减去1,作为新的end值,因为middle值是跟end对应的元素值是相等的,所以即使出现比如10,10,10这种情况,我们去除掉最后一个十也不影响我们最终能找出最小值是10。
代码如下:
class Solution {
public:
int findMin(vector<int>& nums)
{
int size = nums.size();
if(nums.size() == 0)return 0;
int small = 0, big = size - 1, middle = small + (big - small) / 2;
while(small < big)
{
if(nums[middle] < nums[big])
{
big = middle;
}
else if(nums[middle] > nums[big])
{
small = middle + 1;
}
else
big--;
middle = small + (big - small)/2;
}
return nums[middle];
}
};
2.依旧来使用两个指针p1 = 0,p2 = length - 1指向前一个数组和后一个数组,middle代表两者中间,如果middle指向的值等于p1,p2指向的值,那么无法确定middle到底属于前面的数组还是后面的数组。如果middle属于后面的数组,那么middle到p2之间的值全部都是middle代表的值。否则代表middle属于前面的数组。所以在这种情况下,如果middle到p2的值都一样,那么说明middle肯定在后面的数组中即改变p2变成middle,否则在前面的数组中即改变p1位middle。
代码如下:
class Solution {
public:
int findMin(vector<int>& nums) {
if (nums.size() == 0)return -1;
else if (nums.size() == 1)return nums[0];
int p1 = 0;
int p2 = nums.size() - 1;
int middle = p1;
while (nums[p1] >= nums[p2]) {
if (p1 + 1 == p2) {
middle = p2;
break;
}
middle = p1 + (p2 - p1) / 2;
if (nums[middle] == nums[p1] && nums[middle] == nums[p2]) {
bool back = false;
for (int i = middle; i <= p2; i++) {
if (nums[i] != nums[middle]) {
p1 = middle;
back = true;
break;
}
}
if (!back)p2 = middle;
}
else if (nums[middle] <= nums[p2]) {
p2 = middle;
}
else if (nums[middle] >= nums[p1]) {
p1 = middle;
}
}
return nums[middle];
}
};