题目
题解
这道题相对于力扣81题,难上啦许多,需要考虑多种情况。毕竟这道题你是不知道经历多少次旋转的,而且还是找最小值,
这时候就需要考虑
L与R的关系,要通过L与R的关系判断出数组大致旋转情况
L与R的关系中 加入中间值,这三个值成何种情况同样有对应什么关系。
L与R 会有三种情况
- L == R
- L > R
- 加入中间值 会对应处两种情况
L < R
-
代码
/**
* @param {number[]} nums
* @return {number}
*/
var findMin = function(nums) {
let l = 0;
let r = nums.length - 1;
while(l <= r) {
const mid = (l + r) >> 1;
const curValue = nums[mid];
const lValue = nums[l];
const rValue = nums[r];
if(lValue == rValue) l++;
else if (lValue < rValue) {
if(curValue > lValue && curValue > rValue) r = mid - 1;
else r = mid;
} else {
if(lValue <= curValue && curValue > rValue) l = mid + 1;
else r = mid;
}
}
return nums[r]
};
优化后
/**
* @param {number[]} nums
* @return {number}
*/
var findMin = function(nums) {
let l = 0;
let r = nums.length - 1;
while(l <= r) {
const mid = (l + r) >> 1;
const curValue = nums[mid];
const lValue = nums[l];
const rValue = nums[r];
if(lValue == rValue) l++;
else if (lValue < rValue && curValue > lValue) r = mid - 1;
else if(lValue > rValue && lValue <= curValue) l = mid + 1;
else r = mid;
}
return nums[r]
};
再次优化
/**
* @param {number[]} nums
* @return {number}
*/
var findMin = function(nums) {
let l = 0;
let r = nums.length - 1;
if(nums[l] < nums[r]) return nums[l];
while(l <= r) {
const mid = (l + r) >> 1;
const curValue = nums[mid];
const lValue = nums[l];
const rValue = nums[r];
if(lValue == rValue) l++;
else if (lValue < rValue && curValue > lValue) r = mid - 1;
else if(lValue > rValue && lValue <= curValue) l = mid + 1;
else r = mid;
}
return nums[r]
};
图解
l == r
l > r
l < mid < r 这种情况就很容易划分出小数区域,很明显小数区域在 mid 到 r 之间 可以将左指针移动到mid+1
这种情况下就很难通过mid来划分出小数区域与大数区域,那我们就可以将右指针移动到mid的位置,看左指针与mid的中间值l < r
这种情况下是不是很容易划分出小数区域,和大数区域
但是如果这种情况在数组中间出现呢
-