LeetCode - Search in Rotated Sorted Array II

本文探讨了在存在重复元素时如何优化二分搜索算法,通过引入额外判断来提升搜索效率,特别是在面对大量重复数组时。优化后的算法在时间复杂度上有所改善,同时确保了对不同情况的正确处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这道题麻烦的地方就是不能像没有duplicate时候直接判断有没有bump。

所以,分成三种情况,如果 A[left]<A[mid] 或者 A[left] > A[mid],都可以直接判断左边有没有bump,然后根据左边或者右边的range来决定下一步去哪边。

如果A[left]==A[mid],则无法决定左右两边是range还是bump,所以略过left,移动到下个点进行判断。另一种方法是,利用递归,去搜查mid左右两边,因为此时两边都有可能有target,但比较麻烦,就没有实现了,而且既然还是要搜查整个数组,略过left是比较简单的方法了。

优化前代码如下:

    public boolean search(int[] A, int target) {
        int left = 0;
        int right = A.length-1;
        while(left<=right){
            int mid = (left+right)/2;
            if(A[mid]==target) return true;
            if(A[mid]>A[left]){
                if(A[left]<=target && A[mid]>target){
                    right = mid-1;
                }
                else{
                    left = mid+1;
                }
            }
            else if(A[mid]<A[left]){
                if(A[mid]<target && A[right]>=target){
                    left=mid+1;
                }
                else{
                    right = mid-1;
                }
            }
            else{
                left++;
            }
        }
        return false;
    }

没有太多duplicates的话应该是O(lgn),如果很多的话就是O(n),这时候跟直接遍历数组来找时间复杂度就一样了

唯一可以优化的是,当A[left]==A[mid],无法判断左边的情况,可以此时看看右边的情况,如果右边是range,就可以判断是不是应该去右边继续查找,如果右边是bump,则左边肯定是连续的相等的值而不可能是bump了,就不用去左边找了,如果右边两个值也相等,则两边都得找,因为两边可能有一个是bump,另一个是连续相等的值。优化后对大量重复数组有一点提升。

优化后代码如下:

    public boolean search(int[] A, int target) {
        int left = 0;
        int right = A.length-1;
        while(left<=right){
            int mid = (left+right)/2;
            if(A[mid]==target) return true;
            if(A[mid]>A[left]){
                if(A[left]<=target && A[mid]>target){
                    right = mid-1;
                }
                else{
                    left = mid+1;
                }
            }
            else if(A[mid]<A[left]){
                if(A[mid]<target && A[right]>=target){
                    left=mid+1;
                }
                else{
                    right = mid-1;
                }
            }
            else{
                if(A[mid]<A[right]){
                    if(A[mid]<target && target<=A[right]) left = mid+1;
                    else right = mid-1;
                }
                else if(A[mid]>A[right]) left = mid+1;
                else if(A[mid]==A[right]) left++;
            }
        }
        return false;
    }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值