把一个数组最开始的若干个元素搬到数组的末尾

本题起初的想法就是暴力,没错!就是从第一个枚举到最后一个,时间复杂度为O(n); 或者说利用单调性枚举到其中一个小于第一个就退出,平均时间复杂度是。。。。O((1+n)/2)好像还是O(n)啊,没差;

这样的解法并不能得到面试官的认可,也没有体现这道题原有的价值,我们应该寻找更加快捷的解法,二分,让中间结点来确定下一次缩小的范围(eg:3 4 5 1 2,下一次就是5 1 2,下一次就是5 1;当right-left==1的时候退出,时间复杂度是O(log n),但是有些例子并不满足,eg 1 0 1 1 1 和1 1 1 0 1)是的这里还需要特判这样的情况当两边的值和中间的值都相等的时候,我们应该把right的值向前移,类似于暴力,每错,就是枚举(eg:1 1 1 1 1)那么你只能枚举了。


做面试题,不仅仅要把题ac了,还要思考时间和空间复杂度,以及更优解,必须学会边界值的判断防止不必要的错误。


[cpp]  view plain copy
  1. #include<stdio.h>  
  2. #include<iostream>  
  3. #include<vector>  
  4. using namespace std;  
  5.   
  6. class Solution  
  7. {  
  8. public:  
  9.     //暴力。  
  10.     int minNumberInRotateArray1(vector<int> rotateArray)  
  11.     {  
  12.         int mmin=0x7FFFFFFF;  
  13.         for(int i=0; i<rotateArray.size(); i++)  
  14.             mmin=min(rotateArray[i],mmin);  
  15.         return mmin==0x7FFFFFFF?0:mmin;//空数组返回0  
  16.     }  
  17.     //单调性  
  18.     int minNumberInRotateArray2(vector<int> rotateArray)  
  19.     {  
  20.         if(rotateArray.size()==0) return 0;  
  21.         int mmin=rotateArray[0];  
  22.         for(int i=1; i<rotateArray.size(); i++)  
  23.         {  
  24.             if(rotateArray[i]>=mmin)continue;  
  25.             if(rotateArray[i]<mmin) {mmin=rotateArray[i];break;}  
  26.   
  27.         }  
  28.         return mmin;  
  29.     }  
  30.     //二分  
  31.     int minNumberInRotateArray3(vector<int> rotateArray)  
  32.     {  
  33.         if(rotateArray.size()==0) return 0;  
  34.         int mmin=0x7FFFFFFF;  
  35.         int left=0;  
  36.         int right=rotateArray.size()-1;  
  37.         if(left==right||rotateArray[left]<rotateArray[right]) return rotateArray[left];  
  38.         int mm;  
  39.         while(left<right)  
  40.         {  
  41.             mm=(left+right)/2;  
  42.             if(rotateArray[left]==rotateArray[right]&&rotateArray[right]==rotateArray[mm])  
  43.             {  
  44.                 right--;  
  45.             }  
  46.             else if(rotateArray[left]<=rotateArray[mm]&&rotateArray[right]<rotateArray[mm])  
  47.             {  
  48.                 left=mm;  
  49.             }  
  50.             else if(rotateArray[left]>rotateArray[mm]&&rotateArray[right]>=rotateArray[mm])  
  51.             {  
  52.                 right=mm;  
  53.             }  
  54.             if(right-left==1) {mmin=min(rotateArray[left],rotateArray[right]);break;}  
  55.         }  
  56.         return mmin==0x7FFFFFFF?0:mmin;//空数组返回0  
  57.     }  
  58. };  
  59. int main()  
  60. {  
  61.     Solution so;  
  62.     vector<int> arr;  
  63.     int n,a;  
  64.     scanf("%d",&n);  
  65.     while(n--){  
  66.         cin>>a;  
  67.         arr.push_back(a);  
  68.     }  
  69.     int ans1=so.minNumberInRotateArray1(arr);  
  70.     printf("%d\n",ans1);  
  71.     int ans2=so.minNumberInRotateArray2(arr);  
  72.     printf("%d\n",ans2);  
  73.     int ans3=so.minNumberInRotateArray3(arr);  
  74.     printf("%d\n",ans3);  
  75.     return 0;  
  76. }  
题目链接: http://www.nowcoder.com/practice/9f3231a991af4f55b95579b44b7a01ba?rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值