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

class Solution {
    //nums[mid]要么在较大一半
    //要么在较小一半
    //注意范围缩减至两个和一个的时候的处理就行了
    public int findMin(int[] nums) {
        //if(nums.length==1)return nums[0];
        int lo=0;
        int hi=nums.length;
        int mid=0;
        while(lo<hi){
            mid=lo+(hi-lo)/2;
            if(nums[mid]>nums[hi-1]){//
                //中点在较大半边,向右找  
                lo=mid+1;
            }
            else if(nums[mid]<nums[hi-1]) 
                hi=mid+1; 
            else{//要么只剩两个,mid是靠右的。要么是唯一一个
                if(mid-1>=0)
                    return Math.min(nums[mid-1],nums[mid]) ;
                 else
                    return nums[mid];
            }
                  
        }
        return nums[lo];
        
    }
}

二分查找切割区间注意:
中点偏左,mid要给左边;
中点偏右,mid要给右边。
否则一些样例不会通过。
如以下错误解答,可以解决一部分样例:

class Solution {
    //考虑只有两个元素,策略选择:
    //中点计算如果靠左,就要把中点分配给左半边
    //中点计算如果靠右,就要把中点分配给右半边
    //否则不会跳出循环
    //靠右还是靠左,在于hi是开区间还是闭区间
    public int findMin(int[] nums) {
        //if(nums.length==1)return nums[0];
        int lo=0;
        int hi=nums.length;
        int mid=0;
        while(lo<hi){
            mid=lo+(hi-lo)/2;
            if(nums[mid]>nums[hi-1]){
                lo=mid+1;//中点偏右,mid给了左边,不对吧
            }
            else
                hi=mid;        
        }
        
        return nums[lo];
        
    }
}
posted @ 2021-08-01 21:16  wsshub  阅读(31)  评论(0)    收藏  举报