//感想:

1.对于这两题,我真的是做到吐,这篇博客本来是昨晚准备写的,但是对于这个第二题,我真的做到头痛,实在是太尼玛的吐血了,主要是我也是头铁,非要找到那个分界点。

2.其实之前在牛客网上做过非常类似的题目,当时就做的特别痛苦,后来做完也没总结,导致现在做又不知道思路了,不过好歹留下了代码,再次做的时候,看看之前的代码,再结合这道题目的要求也是做完了。

思路:对于33题。

题目要求要logn的,我们对自己要求也要严格一点,所有的都用二分来做,这题目其实是变种的二分,因为正常的二分是找寻一个target值,但是我们现在不是找一个target,而是去找这个排序数组的分界点,对于没有重复元素的,就比较容易了,

所以它只有这种类型,找分界点还是比较容易的。无论是找最大的,还是最小的,都是可以的,这里的二分法要格外注意左右两边的边界移动情况。这是找的最大值的下标,来看看这个helper函数

while(l<=r)
        {
             if(nums[l]<=nums[r])
                 return r;
            int mid=l+(r-l)/2;
            if(nums[mid]>nums[l])
                l=mid;
            else
                r=mid-1;
        }
        return l;

首先如果nums[l]<=nums[r],那么这直接就是一条斜线,可以直接返回右边界,如果nums[mid]>nums[l],说明还在上升,移动左下标指向mid,记住
现在找的是最大值,所以不能让l=mid+1,而是等于mid,不然可能会错过最大值,else 直接让r=mid-1,因为不在上升就肯定在下边,所以直接等于
就行了,继续这样循环,直到右边界移出左边界,那时候我们返回l就行了。感觉还是可以的,主要是情况没有那么复杂,下面就是下一题,原本想做一篇
写的,但是感觉写的太臃肿了,还是在写一篇吧。

class Solution {
    public int search(int[] nums, int target) {
        if(nums==null||nums.length==0)
            return -1;
        if(nums.length==1)
            return target==nums[0]?0:-1;
        int l=0;
        int r=nums.length-1;
        int i=helper(nums,l,r);

        if(target>=nums[0])
            return helper1(nums,l,i,target);
        else
            return helper1(nums,i+1,r,target);
    }
    public int helper1(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 helper(int[] nums,int l,int r)
    {
        while(l<=r)
        {
             if(nums[l]<=nums[r])
                 return r;
            int mid=l+(r-l)/2;
            if(nums[mid]>nums[l])
                l=mid;
            else
                r=mid-1;
        }
        return l;
    }
}
01-01 03:14