旋转数组的最小数字-递归解法
题目描述
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。
输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。
NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
输入
[3,4,5,1,2]
返回值
1
解题思路
1.标签上写的是二分,示意我用二分法做。虽然二分法常用非递归做,但用递归可以更好地表达思路,而且写得快,因此本题我用递归做。
2.首先注意题干中的非递减排序,这让我联想到一条y=x直线,数组的选择就是截取直线前端一部分,平移到后面,成为一个分段线性函数。因此我们得到了几何上的直观揭示:数组的旋转即部分直线的平移。
3.接着我们要二分了,选取中点,即在分段线性函数中间砍一刀。假设最小数字在砍开的右侧,那么砍开的两侧各有什么特点?
4.左侧依然线性,右侧是分段的,各自表现为左端点<右端点,左端点>右端点.因此左端点>右端点的这侧存在最小数字。接着我们分割这侧即可。
5.和其他人不同的是,我没有拿中点的值和端点值进行比较,因为我觉得两侧端点值的关系已经能判断出最小值在哪侧了。
代码
class Solution { public: int helper(vector<int> &rotateArray,int start,int end){ if(start==end)return rotateArray[start]; else{ int mid = (start + end)/2; if(rotateArray[start]<rotateArray[end]){ return rotateArray[start]; }else{ int left = helper(rotateArray,start,mid); int right = helper(rotateArray,mid+1,end); if(left>right)return right; else return left; } } } int minNumberInRotateArray(vector<int> rotateArray) { if(rotateArray.size()==0)return 0; return helper(rotateArray, 0, rotateArray.size()-1); } };