题目
解题
题目中是将一个升序数组在某一位将其数组旋转,这样就会造成两片升序搜索区
第一处:数组第一位到数组中值最大的一位(也就是数组旋转前数组最后一位)该区域数值普遍偏大,叫大数区
第二处:数组中值最小的一位(也就是数组旋转前的第一位)到 数组最后一位 该区域数值都是旋转前数组第一位到旋转位置-1 的值 相对于后面此时偏小 叫小数区
这题考察就是如何应对这个场景
我们可以将搜索区都抽象出来,我们判断target会在哪个搜索区出现,二分算法取的就是中间值,我们可以拿中间与数组最后一位比较
当 中间值 <= 数组最后一位:这个中间值在小数区,我们就可以判断target是否在小数区,如果不在,说明在左边,但是此时无法保证中间值是数组最小位,说不定左边的才是原数组第一位。将右指针移动,使其搜索左边区域,将左边区域依旧通过中间值划分成两部分,判断target在那个区域
中间 >= 数组最后一位: 这个中间值在大数区,方法大致与上面一样,
但是会有特殊情况: 如果中间值 == nums【k】,这就无法划分区域啦
代码
/*** @param {number[]} nums* @param {number} target* @return {boolean}* 原始数组以升序排列,* left right target mid* 第一种情况: target == mid* 第二种情况:left == mid 此时无法判断数组内的边界* left ++ ;* 第三种情况: mid >= right* 判断target是否在 left - mid 之间* 在的话 将右指针移动 mid -1 不在的话 左指针右移 mid + 1* 第四种情况:mid <= right* 判断targe 是否在 mid - right 之间* 在的话将左指针移动 mid + 1不在的话 右指针左移 mid - 1* [1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1]*/var search = function(nums, target) {let l = 0;let r = nums.length - 1;let minIndex = 0;while( l <= r) {const mid = (l + r) >> 1;const curValue = nums[mid];if(curValue == target) return true;else if (curValue == nums[l]) {l++;}else if (curValue <= nums[r]){if(target > curValue && target <= nums[r]) {l = mid + 1;} else {r = mid - 1;}}else {if(target < curValue && target >= nums[l]) {r = mid - 1;} else {l = mid + 1;}}}return false;};

