在具有重复元素的旋转排序数组中查找元素

时间:2019-10-15 01:52:32

标签: java arrays algorithm sorting

此代码是解决问题的方法:https://leetcode.com/problems/search-in-rotated-sorted-array-ii/

我在这里应用的逻辑很好地用于在旋转的排序数组中查找没有重复元素的元素。有人可以告诉我需要什么修改才能使其适用于具有重复元素的数组?

[2,5,6,0,0,1,2],目标= 0输出:true [2,5,6,0,0,1,2],目标= 3输出:false

    public int search(int[] nums, int target) {
        if(nums.length== 0) return -1;

        int left= 0; int right= nums.length -1;

        // find the pivot element i.e, the one that breaks the sorted order of the array
        while(left< right){
            int mid= left+ (right- left)/ 2;
            // if mid< right that means this much part of the array is sorted
            // then do binary search on left and mid
            if(nums[mid]< nums[right])
                right= mid;
            // if mid> right that means this part of the array is not sorted
            // then do binary search on mid+1 to right
            else
                left= mid+ 1;
        }
        int pivot= left;
        int index= -1;
        // if target is between pivot till end then call binary search on that
        if(target>= nums[pivot] && target<= nums[nums.length- 1]){
            index= binarySearch(nums, target, pivot, nums.length- 1);
        }    
        // if target is between start and pivot then call binary search on that
        else{
            index= binarySearch(nums, target, 0, pivot -1);
        }  

        return index;
    }

    // binary search returning index of the mid element
    public int binarySearch(int[] nums, int target, int s, int e){
        while(s<= e){
            int mid= s + (e-s)/ 2;
            if(nums[mid]== target)
                return mid;
            else if(target> nums[mid])
                s= mid+ 1;
            else
                e= mid -1;
        }
        return -1;
    }

1 个答案:

答案 0 :(得分:0)

算法中的问题是,不确定重复值时是否找到确切的枢轴。 例如,对于数组[8,9,2,2,4,5,6],算法将元素定位为第4个位置(从0开始为元素3)。 这样,数组的左侧部分将为[8,9,2],该数组未排序,因此二进制搜索无效。

一个非常简单的解决方案是找到两个枢轴(我们叫left_pivot和right_pivot)。 right_pivot正是您已经找到的那个,并且被定义为“具有数组最低值的元素”。\ left_pivot被定义为“具有数组最高值的元素”,您可以轻松进行修改:

       while(left< right){
            int mid= left+ (right- left)/ 2;
            if (mid * 2 < right)
                mid = mid + 1
            // if mid< right that means this much part of the array is sorted
            // then do binary search on left and mid
            if(nums[mid]< nums[right])
                right= mid-1;
            // if mid> right that means this part of the array is not sorted
            // then do binary search on mid+1 to right
            else
                left= mid;
        }

然后将从索引0到索引left_pivot(而不是数据透视表1)对数组的左侧进行二进制搜索,并从索引right_pivot到length-1进行数组右侧的二进制搜索