leetcode雕虫小技medium 81. Search in Rotated Sorted Array II

题干:https://leetcode.com/problems/search-in-rotated-sorted-array-ii/

 

这题是上一题: https://leetcode.com/problems/search-in-rotated-sorted-array/ 的进阶版,所以看本文时最好先看过我上一篇帖子

去掉了不重复的条件限制,不要小看这个条件约束,因为当有重复时,会发生如下变化:

1,我们找pivot的方法要变,将不能再用二分法,举个极端的例子,有整个input全是1,中间突然变异出一个2,你能通过二分法确定这个2是在左半边还是右半边吗?当然不能,那么能应对这种case的方法就是线性遍历,时间复杂度瞬间变O(n)

2,在确定pivot后,你能确定要搜索的target是出现在左侧还是右侧吗?同样不能,有可能两边都会出现,所以要两侧都搜。

好在这个本身不影响时间复杂度,并且二分搜索法在两段内都能用。

 

基于以上思想,把之前那题的代码稍微改改,就可以work了:

package com.example.demo.leetcode;

public class SearchinRotatedSortedArrayII {
    private int findPivotIndex(int[] nums, int startIndex, int endIndex){
        for(int i=startIndex;i<=endIndex;i++){
            if(i>0 && nums[i]<nums[i-1]){
                return i;
            }
        }

        return -1;
    }

    private  int binarySearch(int[] nums, int startIndex, int endIndex, int target){
        if(startIndex>endIndex){
            return -1;
        }
        if(startIndex==endIndex){
            return nums[startIndex]==target?startIndex:-1;
        }

        int midIndex = (startIndex+endIndex)/2;
        if(target==nums[midIndex]){
            return midIndex;
        }else if(target>nums[midIndex]){
            return binarySearch(nums, midIndex+1, endIndex, target);
        }else{
            return binarySearch(nums, startIndex, midIndex-1, target);
        }
    }

    public int indexSearch(int[] nums, int target) {
        if(nums.length<1){
            return -1;
        }

        int pivot = findPivotIndex(nums, 0, nums.length-1);
        System.out.println("pivot is: "+ pivot);
        if(pivot==-1){
            // already in order
            return binarySearch(nums, 0, nums.length-1, target);
        }
        int indexInLeft = binarySearch(nums, pivot, nums.length-1, target);
        int indexInRight = binarySearch(nums, 0, pivot-1, target);

        if(indexInLeft!=-1){
            return indexInLeft;
        }

        if(indexInRight!=-1){
            return indexInRight;
        }

        return -1;
    }

    public boolean search(int[] nums, int target) {
        int index = indexSearch(nums, target);
        System.out.println("one target index: "+ index);
        if(index==-1){
            return false;
        }else{
            return true;
        }
    }

    public static void main(String[] args) {
        SearchinRotatedSortedArrayII demo = new SearchinRotatedSortedArrayII();
        int[] nums = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
        int target = 2;
        boolean ret = demo.search(nums, target);
        System.out.println(ret);
    }
}

 

 

反思:对数组的敏感度不够,一开始并没有想到说pivot的寻找时间复杂度会从O(log(n))变成O(n)

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值