版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
寻找旋转排序数组中的最小值 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
说明:
这道题是 寻找旋转排序数组中的最小值 的延伸题目。
允许重复会影响算法的时间复杂度吗?会如何影响,为什么?
解题思路:这一题是寻找旋转排序数组中的最小值的升级版,主要难点在于数组中可能存在重复的元素。下面是借鉴别人的思想。
int findMin(int* nums, int numsSize){
int left,right,mid,cur_value,min_value,flag;
left=0;
right=numsSize-1;
if(numsSize==0){
return -1;
}
while(left<=right){
flag=0;
mid=left+(right-left)/2;
cur_value=nums[mid];
if(mid+1<numsSize&&cur_value>nums[mid+1]){
return nums[mid+1];
}
if(mid-1>=0&&cur_value<nums[mid-1]){
return cur_value;
}
if(cur_value>nums[left]||cur_value>nums[right]){
left=mid+1;
}
else if(cur_value<nums[left]||cur_value<nums[right]){
right=mid-1;
}
else if(cur_value==nums[left]){
right=right-1;
}
}
return nums[0];
}
我自己的思路,既然涉及到nums[mid]有可能和左端点和右端点相等,那么我就遍历左边是否有不同的点,如果有,就代表右边一定都是一样的数字,那么进入左边,反之进入右边,这也就找到了二分的依据,但是时间复杂度相较于上方,由O(log(n))升高到了O(nlog(n))。
int findMin(int* nums, int numsSize){
int left,right,mid,cur_value,min_value,flag;
left=0;
right=numsSize-1;
if(numsSize==0){
return -1;
}
while(left<=right){
flag=0;
mid=left+(right-left)/2;
cur_value=nums[mid];
if(mid+1<numsSize&&cur_value>nums[mid+1]){
return nums[mid+1];
}
if(mid-1>=0&&cur_value<nums[mid-1]){
return cur_value;
}
if(cur_value>nums[left]||cur_value>nums[right]){
left=mid+1;
}
else if(cur_value<nums[left]||cur_value<nums[right]){
right=mid-1;
}
else{
for(int i=0;i<mid;i++){
if(nums[i]!=cur_value){
flag=1;
}
}
if(flag){
right=mid-1;
}
else{
left=mid+1;
}
}
}
return nums[0];
}