33. 搜索旋转排序数组

 

  • 翻转点在前半部分 nums[mid]<=nums[low]
    • 而后半部分是单调递增的,比较好判断。可以判断如果 nums[mid] < target <= nums[high] ,去后半部分
    • else 去后半部分
  • else 翻转点在后半部分 nums[mid]>nums[low]
    • 而前半部分是单调递增的,比较好判断。可以判断如果 nums[low] <= target < nums[mid], 去前半部分
    • else 去前半部分
class Solution {
    public int search(int[] nums, int target) {

        int low =0;
        int high = nums.length-1;
        // 注意条件是 low<=high
        while(low <= high) {
            // [3,1] target 是 1 的情况,如果这里没有 +1,low,mid是0,那high=mid-1就是-1了
            int mid = low + (high - low + 1)/2;
            if (target == nums[mid]) {
                return mid;
            }
            // 翻转点在前半部分。后半部分是单调递增的
            if (nums[mid] < nums[low]) {
                // 后半部分是单调递增的。这里是去后半部分的情况
                if (target > nums[mid] && target <= nums[high]) {
                    // 前面 if (target == nums[mid]) 就返回了,所以这里可以排除 mid
                    low = mid+1;
                }
                else {
                    // 前面 if (target == nums[mid]) 就返回了,所以这里可以排除 mid
                    high = mid-1;
                }
            }
            // 翻转点在后半部分+正好在中点。前半部分是单调递增的。
            else {
                // 前半部分是单调递增的。这里是去前半部分的情况
                if (target >= nums[low] && target< nums[mid]) {
                    high = mid - 1;
                }
                else {
                    low = mid + 1;
                }
            }
        }
        return -1;
    }
}

 

153. 寻找旋转排序数组中的最小值

class Solution {
    public int findMin(int[] nums) {
        int low = 0;
        int high = nums.length - 1;
        while(low<=high) {
            int mid = low + (high - low)/2;
            // 初始时是全部,一定不是一个单调增区间
            // 后面一直往有翻转点的区间走
            if (nums[low] <= nums[high]) {
                return nums[low];
            }
            // 最小值一定在翻转点所在的区间。
            // 翻转点在前半部分,去前半部分
            if (nums[mid]<nums[low]) {
                // int mid = low + (high - low)/2; 比如1.5要算成1,因此要弥补前半部分。这里不用-1
                high = mid;
            }
            // 否则翻转点在后半部分,去后半部分
            else {
                // int mid = low + (high - low)/2; 比如1.5要算成1,因此要用后半部分弥补前半部分。这里要+1
                low = mid+1;
            }
        }
        return -1;
    }
}