num153. 寻找旋转排序数组中的最小值
思路:
-
咱就是说,这道题本身是可以水过的,直接for一遍就过了,咳咳,附上第一个思路代码
-
因为题目要求是O(logn)解决,我感觉应该是二分查找,一看题解果然是,附上代码
-
因为当前是由递增数组经过几次旋转变成的,所以可以找到以下规律
-
当左值< 中值,中值< 右值,左值< 右值,中值位置变成右边界
右 中 左
-
当左值<中值,中值>右值,左值>右值,中值位置变成左边界
中 左 右
-
当左值>中值,中值< 右值,左值>右值,中值位置变成右边界
左 右 中
-
-
由上图所示一共有三种可能的情况的,进行分析之后,可以归纳总结两类情况,及为
- 中值>右值
- 中值<右值
-
通过比较中值,可以判断出边界收缩的方向
-
细节问题:
- 因为是一个单调递增数列,所以不会存在
nums[mid] = nums[right]
的情况 - while循环条件为
left < right
- 最小值一定在搜索区间里
mid = left + (right - left) / 2
;- 最后分析一下退出循环的条件
- 输入数组只有一个数,左右边界位置直接重合,不进入循环直接输出
- 如果输入数组超过两个数,最后数组里会剩下两个数
num[left]
和num[mid]
,以及nums[right]
,这里的位置是left == mid == right - 1
- 按照代码中的循环条件结束后,
right = mid
,使得left == right
,左右边界位置重合,循环结束,nums[left]
、nums[mid]
、nums[right]
都保存了最小值。
二分查找参考了其他大神的题解,原题解连接如下:二分查找:为什么左右不对称?只比较mid与right的原因(C++, Java, Python3)
- 因为是一个单调递增数列,所以不会存在
代码一:
class Solution {
public:
int findMin(vector<int>& nums) {
int min = 5000;
for(int i = 0; i < nums.size(); i++){
if(nums[i] < min) min = nums[i];
}
return min;
}
};
代码二
class Solution {
public:
int findMin(vector<int>& nums) {
int left, right, mid;
left = 0, right = nums.size() - 1, 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;
}
}
return nums[left];
}
};