题目描述
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
基本思想:利用两个指针left,right分别指向数组的第一个元素和最后一个元素。按照题目的规则,第一个元素应该大于或等于最后一个元素。然后找到数组的中间元素,分以下几种情况:
1. {3,4,5,1,2}: mid>left 则在[mid,right]之间继续查找;
2. {5,1,2,3,4}: mid<right ,则在[left,mid]之间继续查找;
3. {1,2,1,1,1}: left = mid = right, 则从头到尾进行遍历一边数组,若找到比left值校的则返回最小的,否则返回left的值。
#include <iostream> #include <algorithm> #include "string.h" #include "stdio.h" #include <vector> #include <deque> #include <stack> #include<map> #include<utility> #include "math.h" using namespace std; class Solution { public: int minNumberInRotateArray(vector<int> rotateArray) { if(rotateArray.size() == 0) return 0; int left = 0; int right = rotateArray.size()-1; return minNumber(rotateArray,left,right); } int minNumber(vector<int> arr,int left,int right) { int mid = left+(right-left)/2; if(right-left <= 1) return arr[left]<=arr[right]?arr[left]:arr[right]; if(arr[left]<arr[right]) return arr[left]; if(arr[left]>=arr[right]) { if(arr[mid]>arr[right])//4 5 6 7 8 9 1 2 3 { return minNumber(arr,mid+1,right); } if(arr[left]>arr[mid])//7 8 9 1 2 3 4 5 6 { return minNumber(arr,left,mid);//mid也可能是最小的 } } if(arr[left]==arr[right]&& arr[left]==arr[mid]) { for(int i=0;i<arr.size();i++) { if(arr[i]<arr[left]) { return arr[i]; } } return arr[left]; } return -1; } }; int main() { vector<int> arr; arr.push_back(2); arr.push_back(1); arr.push_back(2); arr.push_back(2); arr.push_back(2); Solution solution; int res = solution.minNumberInRotateArray(arr); cout<<res<<endl; }