Rotate the minimum number of the array (click the link to enter the title)

describe

Moving the first elements of an array to the end of the array is called array rotation. Enter a rotation of a non decrementally sorted array and output the smallest element of the rotated array.

NOTE: all elements given are greater than 0. If the array size is 0, please return 0.

Example 1

input: [3,4,5,1,2]

return value: 1

Method 1: linear traversal, define a min variable to store the minimum value, then traverse the array, update min in case of small, and finally output min. The code is simple, but the time complexity is O(N). Not recommended.

class Solution { public: int minNumberInRotateArray(vector<int> rotateArray) { int min = rotateArray[0]; for(const auto& val : rotateArray) { if(val < min) min = val; } return min; } };

Method 2: define two variables slow and fast, point to the first two elements of the array, and compare slow and fast in turn. If slow < = fast, then slow + +, fast + +. If slow > fast is encountered, then fast is the value we are looking for. This is the same as the method. There is no optimization. In extreme cases, for example, the minimum number is at the end, which is also at the O(N) level.

However, problems arise when the array is as follows. Therefore, we add a flag bit flag. When slow and fast move backward and still have no slow > fast, we output the first element of the array.

class Solution { public: int minNumberInRotateArray(vector<int> rotateArray) { if(rotateArray.size() == 0) return 0; int flag = 0; int slow = 0; int fast = slow + 1; while(fast < rotateArray.size()) { if(rotateArray[slow] <= rotateArray[fast]) { slow++; fast++; flag = 1; } else return rotateArray[fast]; } if(flag != 0) return rotateArray[0]; else return 0; } };

Method 3: according to the analysis of method 2, we know that no matter how we rotate, the array will be divided into two parts. Each part is a non decreasing sorted array, and the value of the first half of the array is larger than the second half as a whole, and the result we want to find is on the left or right of the middle position of the array. Therefore, we can use binary search for reference to define a start and end, When defining an int mid = (start + end) > > 1. If we rotate deeply or shallowly, the minimum value is either on the left, right or Mid. if arr[mid] < arr[start], it means that arr[mid] belongs to the second half array, so the value to be found is in the first half array, right = mid. if arr[mid] > = arr[start], it means that arr[mid] and arr[start] belong to the first half array together, Therefore, the value to be found is at the beginning of the second half of the array, left = mid. this process will narrow the [left, right] interval

class Solution { public: int minNumberInRotateArray(vector<int> rotateArray) { //Returns 0 if the size of the array is 0 if(rotateArray.empty()) return 0; //Define start and end, point to the leftmost and rightmost of the array respectively, and define a mid variable to represent the intermediate value int start = 0; int end = rotateArray.size() - 1; int mid = 0; //The loop is entered only when the leftmost element of the array is larger than the rightmost element //If it does not meet the requirements of Figure 2 in the corresponding method 2, the element at the first position in the array is directly returned while(rotateArray[start] >= rotateArray[end]) { //What should we do if there is only one element? If there is only one element, it indicates that the value, that is, the rightmost element, is the value we are looking for if(end - start == 1) { mid = end; break; } //Calculate mid mid = ((start + end) >> 1); //If the values of mid, left and right are equal, we cannot distinguish between the left and right arrays //At this point, we can only traverse the entire array through the linear method to find if(rotateArray[mid] == rotateArray[start] && rotateArray[start] == rotateArray[end]) { //Direct traversal to find int ret = rotateArray[start]; for(int i = start + 1; i < end; i++) { if(ret > rotateArray[i]) ret = rotateArray[i]; } return ret; } //If arr[mid] > = arr[start], it means that both arr[mid] and arr[start] belong to the first half of the array //So the value to be found is at the beginning of the second half of the array, start= mid if(rotateArray[mid] >= rotateArray[start]) start = mid; //If arr[mid] < arr [start], it means that arr[mid] belongs to the second half of the array //So the value to be found is in the first half of the array, end= mid else end = mid; } return rotateArray[mid]; } };