Sword finger offer series (7) - minimum number of rotation array

Keywords: less

The requirements are as follows:
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 an increasing sort 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.

The breakthrough of this problem is to find a feature of this sort array: rotation divides the array into two parts of small array, and each value of the latter small array is smaller than that of the former small array (no special case is considered here, the default is the sorted incremental array, and the elements are not repeated, which will be discussed later)

In this case, we only need to take advantage of the above feature, that is, the minimum value must be in the second array and must be smaller than the minimum value in the first array (the minimum value in the first array is the first value, eg: [3,4,5,1,2], 3). At this time, we can use the method similar to binary search. Let a first subscript traverse the pointer, and a final subscript traverse the pointer. These two pointers point to the first element and the last element respectively. According to the size of its middle value, the scope will be reduced until it is found. The pseudo code is as follows:

If(middle > indexfirst)
                first = middleelse if(middle < indexfirst)
                final = middle;
        else
                //exceptional case

Let's analyze the special case, when there are duplicate values in this array, and it causes the middle and indexfirst to be equal.
There are also two situations:
1) If there is a special case between first and final that all numbers are a certain number, we can only do loop traversal.
2) If the first value is the same as the middle value, but different from the final value, such as [5,5,5,1,1], our algorithm can still deal with this situation. Therefore, this situation does not need to be considered.

To sum up, we can write code:

package com.offer;

public class MinNumberInRotatedArray {
    /*
     * Rotate array to find the minimum value
     * 
     * be careful! Ergodic search is used only when the three bits of the low and high middle bits are exactly the same to prevent 5,5,5,1,2, so special cases should be put in the front
     */
    public static void main(String[] args) {
        int[] a = new int[]{4,5,1,2,3};
        System.out.println(findMinNumber(a));

    }

    public static int findMinNumber(int[] array){
        if (array == null || array.length <= 0) {

            throw new RuntimeException("Array is empty or length is less than or equal to zero");
        }
        int low = 0;                    //Low traversal pointer
        int high = array.length - 1;    //High traversal pointer
        if (array.length == 1) {        //Only one element
            return array[0];    
        }
        int result = 0;                 //minimum value
        while(Math.abs(high - low) != 1){
            if (array[low] == array[high] && array[high] == array[(low + high) >> 1]) {
                //Middle value and low element are equal to high element, cannot be judged, must traverse query
                for (int i = 0; i < array.length; i++) {
                    result = result > array[i] ? array[i] : result;
                }
                break;      //Jump out of the while loop or it will execute indefinitely!

            }else if(array[(low + high) >> 1] < array[low]){
                //Bounded by the minimum value with the middle value at the back
                high = (low + high) >> 1;

            }else{
                //Bounded by the minimum value, with the middle value in front
                low = (low + high) >> 1;

            }
        }

        result = array[high];





        return result;


    }

}

Posted by phaseonemedia on Sat, 09 May 2020 08:22:21 -0700