《剑指offer》:[11]旋转数组的最小数字
2016-06-03 15:29
537 查看
题目:把一个数组最开始的若干元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小的元素。
例如:数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1.
本题目是直接给的旋转的数组:那么数组如何旋转呢?其实也很简单:
首先确保给数组排序,最好的时间复杂度O(NLogN)。
(1)如果元素的个数是奇数:最中间的元素不动,i和j都指向中间元素的下标。然后i++和j--,同时交换;停止的条件是i<0;
(2)如果元素的个数是偶数:i=n/2-1;j=n/2;i--;j++;停止的条件是i<0;
然后回到正题,求翻转数组的最小数字:
方案一:循环遍历法。此法比较笨,一般这样的方法就不要说了,一般的都能想到。时间复杂度是O(N)。
方案二:二分查找法。
以上面的题目为例:{3,4,5,1,2};
交换以后,被切成两个递增的序列。我们可以发现第一个元素是大于或等于第二个元素的(当然还有特例:如果把前面的0个元素搬到后面,第一元素小于最后的一个元素)。
先看常规的方法:采用二分查找,不断的缩小范围,当最大和最小相邻的时候停止。具体示意如下图一:
图一
注意两种特殊情况:
(1)移动了0个元素,也就是还是原先的序列;
(2)对于如下数组,当第一个指针和第二个指针以及中间元素都相等时,我们无法判断增减序列,进而进行缩小范围。此时我们必须采用顺序查找;
第二种情况如下图二:
图二
具体代码实现如下:
例如:数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1.
本题目是直接给的旋转的数组:那么数组如何旋转呢?其实也很简单:
首先确保给数组排序,最好的时间复杂度O(NLogN)。
(1)如果元素的个数是奇数:最中间的元素不动,i和j都指向中间元素的下标。然后i++和j--,同时交换;停止的条件是i<0;
(2)如果元素的个数是偶数:i=n/2-1;j=n/2;i--;j++;停止的条件是i<0;
然后回到正题,求翻转数组的最小数字:
方案一:循环遍历法。此法比较笨,一般这样的方法就不要说了,一般的都能想到。时间复杂度是O(N)。
方案二:二分查找法。
以上面的题目为例:{3,4,5,1,2};
交换以后,被切成两个递增的序列。我们可以发现第一个元素是大于或等于第二个元素的(当然还有特例:如果把前面的0个元素搬到后面,第一元素小于最后的一个元素)。
先看常规的方法:采用二分查找,不断的缩小范围,当最大和最小相邻的时候停止。具体示意如下图一:
图一
注意两种特殊情况:
(1)移动了0个元素,也就是还是原先的序列;
(2)对于如下数组,当第一个指针和第二个指针以及中间元素都相等时,我们无法判断增减序列,进而进行缩小范围。此时我们必须采用顺序查找;
第二种情况如下图二:
图二
具体代码实现如下:
#include<iostream> using namespace std; int FindOrder(int *array,int length); int FindMin(int *array,int length); int arr1[5]={3,4,5,1,2}; int arr2[5]={1,0,1,1,1}; int FindMin(int *array,int length) { if(NULL==array || length <=0) throw "INVALID INPUT!"; int index1=0; int index2=length-1; int MidInde=index1;//十分必要,因为这个事避免上述说的注意1时的特殊情况; while(array[index1]>=array[index2]) { if(1==index2-index1) return array[index2]; MidInde=(index1+index2)/2; if(array[index1]==array[index2] && array[index2]==array[MidInde])//特殊情况(2); return FindOrder(array,length);//顺序查找; if(array[MidInde]>=array[index1]) index1=MidInde; if(array[MidInde]<=array[index2]) index2=MidInde; } return array[index1]; } int FindOrder(int *array,int length) { int min=array[0]; for(int i=0;i<length;i++) { if(min>array[i]) { min=array[i]; } } return min; } int main() { cout<<"In arr1,the min is :"<<FindMin(arr1,5)<<endl; cout<<"In arr2,the min is :"<<FindMin(arr2,5)<<endl; system("pause"); return 0; }运行结果:
相关文章推荐
- jQuery .tmpl(), .template()学习
- 亲测!Jquery2.0不支持IE8-了
- ArcGIS JavaScript API调用Google、天地图、百度等第三方在线地图服务
- Win8.1系统下安装nodeJS
- JavaScript浏览器对象之一Window对象详解
- [置顶] json字符串和字典、数组之间互转
- (java)美团一面之(Populating Next Right Pointers in Each Node)
- 关于在ubuntu系统下nodejs grunt 或者coffee失效的问题
- 前端开发中的JS调试技巧
- node-inspector使用
- jquery模板jquery.tmpl.js使用教程
- Jquery根据name取得所有选中的Checkbox值
- Zookeeper可视化工具。 ZK 安装 node-zk-browser。2015.10.22亲测可用
- 前端资源集合
- jQuery深入之源码解析(一)
- 从零开始学_JavaScript_系列(23)——css<5>滚动条,Tab,spellcheck,img放置
- 理解Java中的弱引用(Weak Reference)
- webpack入门(四)——webpack loader 和plugin
- JQuery 复制粘贴上传图片插件(textarea 和 tinyMCE)
- MapReduce源码分析之LocatedFileStatusFetcher