Leetcode No.81 search rotation sort array II (dichotomy)

1, Title Description

It is known that there is an integer array nums arranged in non descending order, and the values in the array do not have to be different from each other.

Before passing to the function, Num rotates on a previously unknown subscript k (0 < = k < num.length), making the array [num [k], Num [K + 1],..., Num [n-1], Num [0], Num [1],..., Num [k-1]] (subscripts count from 0). For example, [0,1,2,4,4,4,5,6,6,7] may become [4,5,6,6,7,0,1,2,4,4] after rotation at subscript 5.

Give you the rotated array num and an integer target. Please write a function to judge whether the given target value exists in the array. If the target value target exists in nums, it returns true; otherwise, it returns false.

Example 1: Input: num = [2,5,6,0,0,1,2], target = 0 Output: true

Example 2: Input: num = [2,5,6,0,0,1,2], target = 3 Output: false

Tips:

1 <= nums.length <= 5000 -10^4 <= nums[i] <= 10^4 The title data ensures that nums rotates on a subscript unknown in advance -10^4 <= target <= 10^4

Advanced:

This is an extension of the search rotation sorting array. The nums in this question may contain duplicate elements. Does this affect the time complexity of the program? What impact will it have and why?

2, Problem solving ideas

Using binary search, initialize two variables Low = 0, high = num.length-1

1,mid=(low+high)/2

2. If num [mid] is equal to target, the subscript mid is returned

3. When num [mid] is less than num [high], it means that the right side of mid - > high is orderly. Judge whether the target is on the right side, otherwise look to the left

4. When num [mid] is greater than num [high], it indicates that the left side of low - > mid is orderly. Judge whether the target is on the left side, otherwise look to the right side

5. When low > high, it means that it is not found, and - 1 is returned

When there are duplicate elements in the array, a[l]=a[mid]=a[r] may occur during binary search. At this time, it is impossible to judge which of the interval [l,mid] and the interval [mid+1,r] is ordered.

For example, Num = [3,1,2,3,3,3,3], target=2. It is impossible to judge which of interval [0,3] and interval [4,6] is ordered in the first dichotomy.

In this case, we can only add one to the left boundary and subtract one from the right boundary between the current two partitions, and then continue the binary search between the new districts.

3, Code

1. Recursion

class Solution {
    public boolean search(int[] nums, int target) {
        int rs=fun(nums, 0, nums.length - 1, target);
        if(rs==-1){
            return false;
        }else{
            return true;
        }
    }
    private int fun(int[] nums, int low, int high, int target) {
        if (low > high)
            return -1;
        int mid = (low + high) / 2;
        if (nums[mid] == target)
            return mid;
        if(nums[mid]==nums[low]&&nums[mid]==nums[high]){
            low++;
            high--;
            return fun(nums, low, high, target);
        }else if (nums[mid] <= nums[high]) {
            //The right side is ordered
            if (nums[mid] <= target && target <= nums[high])
                //The target value is on the right
                return fun(nums, mid + 1, high, target);
            else
                //The target value is on the left
                return fun(nums, low, mid - 1, target);
        }else{
            //The left side is orderly
            if (nums[low] <= target && target < nums[mid])
                //The target value is on the left
                return fun(nums, low, mid - 1, target);
            else
                //The target value is on the right
                return fun(nums, mid + 1, high, target);
        }
    }
}

2. Double pointer

class Solution {
    public boolean search(int[] nums, int target) {
        int n = nums.length;
        if (n == 0) {
            return false;
        }
        if (n == 1) {
            return nums[0] == target;
        }
        int l = 0, r = n - 1;
        while (l <= r) {
            int mid = (l + r) / 2;
            if (nums[mid] == target) {
                return true;
            }
            if (nums[l] == nums[mid] && nums[mid] == nums[r]) {
                ++l;
                --r;
            } else if (nums[l] <= nums[mid]) {
                //The left side is orderly
                if (nums[l] <= target && target < nums[mid]) {
                    //The target value is on the left
                    r = mid - 1;
                } else {
                    //The target value is on the right
                    l = mid + 1;
                }
            } else {
                //The right side is ordered
                if (nums[mid] < target && target <= nums[n - 1]) {
                    //The target value is on the right
                    l = mid + 1;
                } else {
                    //The target value is on the left
                    r = mid - 1;
                }
            }
        }
        return false;
    }
}

4, Complexity analysis

Time complexity: O(n), where n is the length of array nums. In the worst case, the array elements are equal and not target. We need to access all positions to get the result.

Space complexity: O(1).

Posted on Mon, 29 Nov 2021 04:18:31 -0500 by ixos