81 Search in Rotated Sorted Array II

这题是在之前做过的一道题的follow up,之前的题说明了sort array中没有duplicate,但是这题里强调说有duplicate,那么就是要针对这以特点进行特殊处理。

基本逻辑还是一样的

通过left 和 right 夹逼来缩小搜索范围【使用while loop,内部条件是left<=right,是可以相等的,因为left和right都可能是target,但是只有允许left==right,才可能通过 mid=(left+right)/2 来取到right,left是可以在left和right相邻时取到的】,类似于二分法。但是判断的条件比简单的二分法要复杂,因为在sort array中只要判断和 [mid] 的大小就能判断决定是缩小到左还是右,在这里的话,因为是rotated sorted array,那么先要判断哪一边在rotated 之后仍然是 sorted array。一个基本性质的,以mid (或者任意一个元素为分界) 总有一遍是sorted的。

1,左边是sorted,判断是target在左边范围的中间,是则去掉右边,更新right;不是则去掉左边,更新left

2,如果左边不是sorted,那么右边一定是sort,然后按照相同的逻辑判断target是不是在右边,然后对应的通过更新left,right 缩小范围。

如果没有duplicate元素,那么上面两种情况就是整个集合

但是如果有duplicate,则有可能[mid]==[left],那么就无法判断是要选取哪一边进行缩小,貌似是要左边,但是也不能确定更新到什么位置,这个时候只能让left++,直到找到一个比当前[left]要大的一个数。

代码如下,下一道题,就把没有duplicate的代码贴上来。

一些更细节的分析和逻辑的梳理,看自己ppt记录

public class Solution {
    public boolean search(int[] nums, int target) {
        int left=0;
        int right=nums.length-1;
        
        while(left<=right){   // 通过夹逼法缩小范围,类似二分,必须有left==right,因为在target可以是right,只有允许==才能取到right
            int mid=(left+right)/2;
            if(nums[mid]==target) return true;
            
            // 判断左边是否是sorted,如果是,接着判断target在此范围没有,然后就可以update left or right来缩小范围了
            if(nums[mid]>nums[left]){  // 注意了,这里是不能加=的,虽然在no duplicate中说了,要加=号。原因是:出现==的情况有两种:1,相邻;2,duplicate;如果在这里加=,那么出现情况2就会出错,所以不用在这处理,而是留到下面的else那去处理,这样把情况1和2都正确处理了
                if(target>=nums[left] && target<nums[mid]) right=mid-1;
                else left=mid+1;
            }
            // 如果左边不是sort,那么右边一定是sorted,接着判断target在此范围没有,然后就可以update left or right来缩小范围了
            else if(nums[mid]<nums[left]){
                if(target>nums[mid] && target<=nums[right]) left=mid+1;
                else right=mid-1;
            }
            // 最后还有一种情况,就是[mid]==[left],那么就只能通过右移left,知道出现[mid]!=[left],然后就回到以上的判断条件里。
            else left++;
        }
        
        return false;
    }
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值