Sword refers to Offer 11 (Sorting Part 1). The minimum number of rotation array

Problem Description:

Moving the first few elements of an array to the end of the array is called the rotation of the array. Input a rotation of an array sorted in ascending order, output the smallest element of the rotated array. For example, the array [3,4,5,1,2] is a rotation of [1,2,3,4,5] with a minimum value of 1.

Example:

输入:[3,4,5,1,2]
输出:1
输入:[2,2,2,0,1]
输出:0

Problem-solving ideas:

The first few elements of this array are moved to the end of the array, and the front part of the rotated array is sorted according to size.

1. Direct traversal, linear search

class Solution {
    
    
    public int minArray(int[] numbers) {
    
    
        for(int i = 0;i < numbers.length - 1;i++){
    
    
            if(numbers[i + 1] < numbers[i]){
    
    
                return numbers[i + 1];
            }
        }
        return numbers[0];
    }

}

2. Use binary search to achieve

reference link

The topic of binary search (reduction thinking)
is a semi-ordered array. Although traditional binary search tells us that binary search can only be used in ordered arrays, in fact, as long as it is a problem that can be reduced, the binary idea can still be used. .

**Idea:** The most special positions in the array are the left position left and the right position right, compare them with the value of the middle position mid, and then determine where the smallest number appears.

Is it possible to compare the values ​​of the left position left and the middle position mid?
For example: [3, 4, 5, 1, 2] and [1, 2, 3, 4, 5], at this time, the values ​​in the middle position are larger than those on the left, but the minimum value is one at the back and one at the front, so This approach cannot effectively reduce the cure.

Is it okay to compare the values ​​of the right position right and the middle position mid?
For example: [1, 2, 3, 4, 5], [3, 4, 5, 1, 2], [2, 3, 4, 5 ,1], compare the elements at the right position and the middle position, you can further Narrow your search.

Supplementary note: When encountering nums[mid] == nums[right], you can't make a hasty conclusion on which side the smallest number is on, but you can be sure that discarding right will not affect the result.

class Solution {
    
    
    public int minArray(int[] numbers) {
    
    
        //以以下三个旋转数组为例
        //3,4,5,0,1
        //2,2,2,0,1
        //2,3,4,5,1
        int left = 0;
        int right = numbers.length - 1;
        while(left <= right){
    
    
            int mid = (left + right) / 2;
            //当numbers[mid] == numbers[right]时,right位置的元素就可以不用考虑了
            if(numbers[mid] == numbers[right]){
    
    
                right--;
            }else if(numbers[mid] > numbers[right]){
    
    
                left = mid + 1;
            }else{
    
    
                right = mid;
            }
        }
        return numbers[left];
    }
}

3. Using sorting, the following will use bubbling and quick sorting methods to explain this question!

img

Bubble sort O(N^2) sorting principle:

  1. Compare adjacent elements. If the previous element is greater than the latter, swap the positions of the two elements.
  2. Do the same for each pair of adjacent elements, from the first pair at the beginning to the last pair at the end. Finally, the element in the last position is the maximum value.

image-20210827164750118

Counterfeit sort code implementation

//方式一:
class Solution {
    
    
    public int minArray(int[] numbers) {
    
    
        //冒泡排序
        int temp = 0;
        for(int i = 0;i < numbers.length;i++){
    
    
            for(int j = numbers.length - 1;j > i;j--){
    
    
               if(numbers[i] > numbers[j]){
    
    
                    temp = numbers[i];
                    numbers[i] = numbers[j];
                    numbers[j] = temp;
               }
            }
        }
        return numbers[0];
    }
}
//方式二:
class Solution {
    
    
    public int minArray(int[] numbers) {
    
    
        //冒泡排序
        int temp = 0;
        for(int i = numbers.length - 1;i > 0;i--){
    
    
            for(int j = 0;j < i;j++){
    
    
               if(numbers[i] < numbers[j]){
    
    
                    temp = numbers[i];
                    numbers[i] = numbers[j];
                    numbers[j] = temp;
               }
            }
        }
        return numbers[0];
    }
} 
//方式三:
class Solution {
    
    
    public int minArray(int[] numbers) {
    
    
        //冒泡排序
        int temp = 0;
        for(int i = 0;i < numbers.length;i++){
    
    
            for(int j = 0;j < numbers.length - i - 1;j++){
    
    
               if(numbers[j] > numbers[j + 1]){
    
    
                    temp = numbers[j];
                    numbers[j] = numbers[j + 1];
                    numbers[j + 1] = temp;
               }
            }
        }
        return numbers[0];
    }
}

Quick sort sort principle:

  1. First set a cutoff value, through which the array is divided into left and right parts;
  2. Put the data greater than or equal to the cutoff value on the right side of the array, and put the data smaller than the cutoff value on the left side of the array. At this time, each element in the left part is less than or equal to the cutoff value, and each element in the right part is greater than or equal to the cutoff value;
  3. Then, the left and right data can be sorted independently. For the array data on the left, you can also take a boundary value to divide this part of data into left and right parts, and also place a smaller value on the left and a larger value on the right. The array data on the right can also be processed similarly.
  4. Repeating the above process, we can see that this is a recursive definition. After sorting the left part by recursion, recursively sort the order of the right part. When the data in the left and right parts are sorted, the sorting of the entire array is completed.

image-20210827204321861

Segmentation principle:

The basic idea of ​​​​slicing an array into two sub-arrays:

1. Find a reference value and use two pointers to point to the head and tail of the array respectively;

2. First search for an element smaller than the reference value from the tail to the head, stop when the search is found, and record the position of the pointer;

3. Then search for an element larger than the reference value from the head to the tail, stop when the search is found, and record the position of the pointer;

4. Exchange the elements at the current left pointer position and right pointer position;

5. Repeat steps 2, 3, and 4 until the value of the left pointer is greater than the value of the right pointer and stop.

image-20210827210811274

image-20210827210826070

image-20210827210848637

Quick sort code implementation

class Solution {
    
    
    public int minArray(int[] numbers) {
    
    
        //设定left的初始位置为0,right的初始位置为数组最大索引处的
        int left = 0;
        int right = numbers.length - 1;
        quickSort(numbers,left,right);
        return numbers[0];
    }


    public static void quickSort(int[] numbers,int left, int right){
    
    
        //约束条件,当左指针超过右指针时,直接结束
        if (left > right){
    
        // 结束条件
            return;
        }
        //初始化low和high的位置,以及第一个基准位
        int low = left;
        int high = right;
        int base = numbers[left];  //第一个位基准位
        int temp;
        //设定快速排序
        while (low < high){
    
    
            while (numbers[high] >= base && low < high){
    
    ///找到小于基准位的数
                high--;
            }
            while (numbers[low] <= base && low < high){
    
    // 找到大于基准位的数
                low++;
            }

            if (low < high){
    
                         // 交换
                temp = numbers[high];
                numbers[high] = numbers[low];
                numbers[low] = temp;
            }else{
    
    
                break;
            }
        }
        //
        numbers[left] = numbers[low];                 // 交换基准位和中间值
        //
        numbers[low] = base;
        quickSort(numbers,left,low-1);      //左边递归
        quickSort(numbers,low+1,right);       // 右边递归
    }   
}

Guess you like

Origin blog.csdn.net/Royalic/article/details/119972728