leetcode 33和 leetcode81 II

//接上上一篇博客,继续这个题目,现在数组中会有重复元素,情况将会变得十分复杂,比如说1,1,1,1,1   或者1,1,3,1再来 3,3,3,1,1,1,3,这些都是可以的,都是符合题目要求的,如果有疑问,自己想想。那么这么复杂怎么找最大点呢?我找不到,我去看了我牛客网当时的思路,当时找的是最小值,我觉得没问题,我就这么找了。

下面给出代码:

class Solution {
    public boolean search(int[] nums, int target) {
         if(nums==null||nums.length==0)
            return false;
        if(nums.length==1)
            return target==nums[0]?true:false;
        int l=0;
        int r=nums.length-1;
        int i=find(nums,l,r);
        while(i-1>=0&&nums[i-1]==nums[i])
            i--;
        
            if(binarySearch(nums,l,i-1,target)!=-1||binarySearch(nums,i,r,target)!=-1)
                return true;
            else
                return false;
      
            
    }
     public int binarySearch(int[] nums,int l,int r,int target)
    {
        while(l<=r)
        {
            int mid=l+(r-l)/2;
            if(nums[mid]==target)
                return mid;
            else if(nums[mid]>target)
                r=mid-1;
            else
                l=mid+1;
        }
        return -1;
    }
    public int find(int[] nums,int l,int r)
    {
        while(l<=r)
        {
            if(nums[l]<nums[r])
                return l;
            int mid=l+(r-l)/2;
            if(nums[mid]>nums[l])
                l=mid+1;
            else if(nums[mid]<nums[r])
                r=mid;
            else 
                l++;
        }
        return r;
    }
}

 将核心代码拿出来

public int find(int[] nums,int l,int r)
    {
        while(l<=r)
        {
            if(nums[l]<nums[r])
                return l;
            int mid=l+(r-l)/2;
            if(nums[mid]>nums[l])
                l=mid+1;
            else if(nums[mid]<nums[r])
                r=mid;
            else 
                l++;
        }
        return r;
    }
对于nums[l]<nums[r],因为现在有重复元素,所以不能加等号,比如说2,2,1,2,不能直接判断了,然后还是求出mid,因为现在我们找最小值了,所以我们右边的就不要动,这里的动指的是+1或者不加
1,直接等于mid,移动l=mid+1,不会错过最小值,可能会错过最大值。如果num[mid]>nums[l],说明现在mid左边是上升的,直接让l=mid+1,如果nums[mid]<nums[r],说明右边是上升的,所以我们
直接r=mid;如果都不满足,进入最后一个else,说明现在遇到了相等值,现在就不能用二分去判断了,只能慢慢的移动一个个来,让l++,这样的话,我们r不会移动,所以不会导致我们错过最小值,直到l移动
过了r,结束循环,返回我们的r,记住很关键的一点,这个r现在是我们找到的最右边的那个最小值,所以当你返回以后,还是需要处理的。
这种情况只有右边全是最小值的时候才会发生,3,1,1,1的时候是最后的一个1,但是如果是3,1,1,1,3返回的就是第一个1了,感觉很奇妙。现在下课了,那么就写到这吧。有什么问题,可以讨论。
原文地址:https://www.cnblogs.com/cold-windy/p/11770254.html