The minimum number of NO.6 rotation array in "sword finger Offer" Java

The minimum number of NO.6 rotation array in "sword finger Offer" Java

Portal: General Catalogue of sword finger Offer

Time: February 9, 2020
Title:
To move the first elements of an array to the end of the array, we call it the rotation of the array.
Input a rotation of a non decrementing array, and output the minimum elements of the rotation array.
For example, array {3,4,5,1,2} is a rotation of {1,2,3,4,5} and the minimum value of the array is 1.
NOTE: all the given elements are greater than 0. If the array size is 0, please return 0.


I found many codes on the Internet and wrote them myself, but even if I can run through the cattle, I can't run through some examples of my own test, such as:

int []a1={2,2,2,2,2,2,1,1,1,2};
int []a2={1,1,1,1,1,1,1};

Later, I found a code of the great God, simple and perfect
Thinking: (refer to the great God FIANCK)
1. Using the idea of dichotomy to reduce the complexity of algorithm
2. Comparing the middle element with the tail element (simpler than the head element), there are only three situations:

array[mid]>array[right]: 
At this time, the mid must be before the minimum value. Operation: left=mid+1;
array[mid]==array[right]:
At this time, it is impossible to determine whether the mid is before or after the minimum value. To avoid skipping the minimum point, you should: right --;
array[mid]<array[right]:
At this time, the mid must be after the minimum value or the minimum value. To avoid skipping the minimum point, you should: right=mid;

In this way, once left moves to the right, it must be at the minimum value:

1. Wait for the right point by point to move left to be equal to left, and return array[left]; 
2. Or more commonly, once you find that array[left] < array [right], you can return array[left],
Don't wait for right to move to left

3. The overall complexity is O (logn). In some special cases, it will degenerate to O(N) [when the array is all equal numbers]

Java code:

/**
 * To move the first elements of an array to the end of the array, we call it the rotation of the array.
 * Input a rotation of a non decrementing array, and output the minimum elements of the rotation array.
 * For example, array {3,4,5,1,2} is a rotation of {1,2,3,4,5} and the minimum value of the array is 1.
 * NOTE: All the given elements are greater than 0. If the array size is 0, please return 0.
 * Special cases: empty array, equal array, non increasing array (eg: {5,5,5,5,5,2,2,2,5,5}), ascending array, single value array
 */
public class MinInRotateArray {
    public int minNumberInRotateArray(int[] array) {
        if(array.length==0) return 0;
        int left=0;
        int right=array.length-1;//Left and right bounds of array
        int mid;
        while(left<right){
            //Ascending array
            if (array[left] < array[right])
                return array[left];
            mid=left+(right-left)/2;

            if(array[mid]>array[right])//mid to the left of minimum
                left=mid+1;//Must be + 1, otherwise there are only two numbers left and the minimum value will fall into a dead cycle at the end
            else if(array[mid]==array[right])//Can't tell if the mid is on the left or the right
                right--;//In order not to skip the minimum, a little trial
            else {right=mid;}//The mid is to the right of the minimum value or the minimum value. To avoid skipping the minimum value, you cannot - 1 here
        }
        return array[left];//Once left reaches the right, it will be at the minimum value, and it will not move again, waiting for right to move to
        //If it's the same as left, just return the value there
    }

    public int minNumberOfIndexInRotateArray(int[] array) {
        if(array.length==0) return 0;
        int left=0;
        int right=array.length-1;//Left and right bounds of array
        int mid;
        while(left<right){

            if (array[left] < array[right])
                return array[left];
            mid=left+(right-left)/2;

            if(array[mid]>array[right])//mid to the left of minimum
                left=mid+1;//Must be + 1, otherwise there are only two numbers left and the minimum value will fall into a dead cycle at the end
            else if(array[mid]==array[right])//Can't tell if the mid is on the left or the right
                right--;//In order not to skip the minimum, a little trial
            else {right=mid;}//The mid is to the right of the minimum value or the minimum value. To avoid skipping the minimum value, you cannot - 1 here
        }
        return left;//Once left reaches the right, it will be at the minimum value, and it will not move again, waiting for right to move to
        //If it's the same as left, just return the value there
    }

    public static void main(String[] args) {
        int []a1={2,2,2,2,2,2,1,1,1,2};
        int []a2={1,1,1,1,1,1,1};
        int []a3={0,1};
        MinInRotateArray min=new MinInRotateArray();
        System.out.println(min.minNumberInRotateArray(a1));
        System.out.println(min.minNumberOfIndexInRotateArray(a1));
        System.out.println(min.minNumberInRotateArray(a2));
        System.out.println(min.minNumberOfIndexInRotateArray(a2));
        System.out.println(min.minNumberInRotateArray(a3));
    }
}
Published 12 original articles, praised 0, visited 581
Private letter follow

Tags: Java

Posted on Thu, 13 Feb 2020 01:24:48 -0500 by opencombatclan