题目
已知一个长度为 n 的数组,预先按照升序排列,经由 1 到 n 次 旋转 后,得到输入数组。例如,原数组 nums = [0,1,4,4,5,6,7] 在变化后可能得到:
若旋转 4 次,则可以得到 [4,5,6,7,0,1,4]
若旋转 7 次,则可以得到 [0,1,4,4,5,6,7]
注意,数组 [a[0], a[1], a[2], …, a[n-1]] 旋转一次 的结果为数组 [a[n-1], a[0], a[1], a[2], …, a[n-2]] 。
153.给你一个元素值 互不相同 的数组 nums ,它原来是一个升序排列的数组,并按上述情形进行了多次旋转。请你找出并返回数组中的 最小元素 。
154.给你一个可能存在 重复 元素值的数组 nums ,它原来是一个升序排列的数组,并按上述情形进行了多次旋转。请你找出并返回数组中的 最小元素 。
一、循环条件:<
1.153&154
参考解析:题解
class Solution {
public:
int findMin(vector<int>& nums) {
int left=0,right=nums.size()-1;
//int res=nums[0];
int len=nums.size();
int mid=0;
while(left<right)
{
mid=(right-left)/2+left;
if(nums[right]<nums[mid])
{
left=mid+1;
}
else if(nums[right]>nums[mid])
{
right=mid;
}
else if(nums[mid] == nums[right]) right--;
}
return nums[left];
}
};
二、循环条件:<=
1.153
代码如下(示例):
class Solution {
public:
int findMin(vector<int>& nums) {
int left=0,right=nums.size()-1;
int res=nums[0];
int len=nums.size();
while(left<=right)
{
int mid=(right-left)/2+left;
//分别求两个区间的最小值
if(nums[left]<=nums[mid])//左有序
{
res=min(res,nums[left]);
left=mid+1;
}
else
{
res=min(res,nums[mid]);
right=(mid-1);
}
}
return res;
}
};
2.154
代码如下(示例):
class Solution {
public:
int findMin(vector<int>& nums) {
int left=0,right=nums.size()-1;
//int res=nums[0];
int len=nums.size();
int mid=0;
while(left<=right)
{
mid=(right-left)/2+left;
//分别求两个区间的最小值
if(nums[left]<nums[right])return nums[left];
//如果二分后的数组是有序数组,则返回最左元素,即为最小
if(nums[left]<nums[mid])//左有序
{
//res=min(res,nums[left]);
left=mid+1;
}
//若最左大于mid元素,则最小元素必定在最左到mid之间(不包括最左,因为最左已经大于mid)
else if(nums[left]>nums[mid])
{
right=mid;
left++;//不同之处
}
else if(nums[mid] == nums[left]) left++;
}
return nums[mid];
}
};