面试题8:旋转数组的最小数字
来源:互联网 发布:单片机中定时器tr管脚 编辑:程序博客网 时间:2024/06/05 19:38
题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。
分析
很自然地,最直观的解法就是设置一个最小值,并顺次检查数组的每一个元素,如果小于最小值,就更新这个值。最后将它输出即可。
最容易想到的往往都不是最优的解法。这种算法的时间复杂度为O(n),没有利用这是一个已排序数组的旋转这个特性。代码从略。
一般我们对一个已排序数组进行查找较好的方法是二分法。所以我们试着用来解这道题。
假设这个数组有n个元素,则它可以分为有旋转和无旋转两种情况(旋转n次也相当于无旋转)。当有旋转时,我们将数组分成左右两部分,他们都是递增的子数组,而最小元素是右子数组的第一个元素,因此可以在两部分里面分别用二分法来查找。而无旋转就相当于有旋转的一个特例(一个子数组为空),所以也可依照此法来解。下面是参考思路:
设数组为arr,其左右元素的下标分别是left和right,我们求得其中间元素的下标mid=left+(right-left)/2;如果arr[mid]>arr[mid],表明mid在左子数组中,此时令left=mid。否则表明mid在右子数组中,令right=mid。继续循环即可。
代码如下
int Min(vector<int> arr){ int left=0,right=arr.size()-1; int mid; if(arr[left]<arr[right]) return left; while(left<right-1) { if(right-left==1) { mid=right; break; } mid=left+(right-left)/2; if(arr[mid]==arr[left] && arr[mid]==arr[right]) return arr[mid]; if(arr[mid]<=arr[right]) right=mid; else if(arr[mid]>=arr[left]) left=mid; } return arr[mid];}
然而,当数组为{1,0,1,1,1}时,使用上述算法是无法找出最小元素的。因为刚开始left=0,right=4,mid=2,此时arr[left]=arr[mid]==arr[right],算法就直接返回1,而数组真正最小的元素是0。所以需要加一个判断条件,如果左中右的值相等时,则需要顺序查找。
int MinInOrder(vector<int> arr){ if(arr.size()<=0) return -1; int min=0; int i; for(i=0;i<arr.size();++i) { if(arr[i]<arr[min]) min=i; } return arr[min];}
然后将
if(arr[mid]==arr[left] && arr[mid]==arr[right]) return arr[mid];
改为
if(arr[mid]==arr[left] && arr[mid]==arr[right]) return MinInOrder(arr);
即可。
以上
如果你有任何想法或是可以改进的地方,欢迎和我交流!
完整代码及测试用例在github上:点我前往
0 0
- 面试题:旋转数组的最小数字
- 面试题8:旋转数组的最小数字 ***
- 面试题8:旋转数组的最小数字
- 【剑指offer】面试题8:旋转数组的最小数字
- 剑指offer面试题8:旋转数组的最小数字
- 剑指Offer:面试题8 :旋转数组的最小数字
- 面试题8:旋转数组的最小数字
- 《剑指offer》面试题8旋转数组的最小数字
- 面试题8-旋转数组的最小数字
- 面试题8 旋转数组的最小数字
- 面试题8 旋转数组的最小数字
- 《剑指Offer》面试题8:旋转数组的最小数字
- 面试题8 旋转数组的最小数字
- 【剑指offer】 面试题8: 旋转数组的最小数字
- 面试题8:旋转数组的最小数字
- 面试题8:旋转数组的最小数字
- 剑指offer-面试题8:旋转数组的最小数字
- 面试题8:旋转数组的最小数字
- 我的理解--关于jmx
- Android OpenGL ES2.0编程教程系列之绘制图形(三)
- 【Android】LruCache简单用法示例
- Android day5:SVN
- javascript中function的call()函数的使用-----替换当前函数中的当前对象
- 面试题8:旋转数组的最小数字
- RecyclerView 解析(二)
- 跟我一起学习VIM - The Life Changing Editor
- 面试题9:斐波那契数列
- Linux设备驱动程序模型
- word中如何修改脚注上方短横线的格式?
- 《JavaScript学习笔记三》if else及function的使用
- Java web 一段代码只执行一次
- nginx笔记