现在的位置: 首页 > 综合 > 正文

编程之美 数组循环移位

2013年09月19日 ⁄ 综合 ⁄ 共 1190字 ⁄ 字号 评论关闭

设计一个算法,把一个含有N个元素的数组循环右移K位,要求时间复杂度为O(N),且只允许使用两个附件变量。比如abcd1234右移4位后为:1234abcd。

法一:

       挨个遍历,每个移动K位,复杂度

  1. RightShift(int* arr,int N, int  K)  
  2.      {  
  3.           
  4.          while(K--)  
  5.              {  
  6.              int t=arr[N-1];  
  7.              for(int i=N-1;i>0;i--)  
  8.                   arr[i]=arr[i-1];  
  9.               arr[0]=t;  
  10.              }  
  11.     }  

法二:可以进一步优化,因为K远大于N时,存在重复移动,即移动存在周期性,周期就是N,所以移动K%=N就可以了

  1. RightShift(int* arr,int N, int  K)  
  2.      {  
  3.          K%=N;  
  4.          while(K--)  
  5.              {  
  6.              int t=arr[N-1];  
  7.              for(int i=N-1;i>0;i--)  
  8.                   arr[i]=arr[i-1];  
  9.               arr[0]=t;  
  10.              }  
  11.     }  

法三:分组逆序排序,具体过程分三步,以abcd1234移动4位为例子

            逆序排列abcd:abcd1234   =>     dcba1234

            逆序排列1234:dcba1234  =>      dcba4321

           逆序排列dcba4321:  dcba4321     =>    1234abcd

  1. Reverse(int*  arr,  int  b,  int  e)  
  2. {  
  3.     for(;b<e;b++,e--)  
  4.          {  
  5.            int tmp=arr[e];  
  6.            arr[e]=arr[b];  
  7.            arr[b]=tmp;  
  8.          }  
  9. }  
  10. RightShift(int* arr,int N, int  K)  
  11. {  
  12.       K%=N;  
  13.       Reverse(arr,0, N-K-1);        
  14.       Reverse(arr, N-K,N-1);        
  15.       Reverse(arr,  0, N-1);  
  16. }

抱歉!评论已关闭.