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

n元一维向量左/右移动 i个位置

2013年10月31日 ⁄ 综合 ⁄ 共 951字 ⁄ 字号 评论关闭

  将一个n元一维向量左移动,或者右移 i个位置,是一道经典的算法题,比如,abcdef左移两位,变成cdefab, 简单的代码使用一个 n元的中间向量完成该工作,能否使用数十个字节的内存空间,用正比于n的时间内完成向量的旋转?

  最简单的办法就是,循环移动K次,每次移动一位。时间复杂度是o(K*n)。代码如下:

  ShitBits(int *arr,int N,int k)

 {

    while(k--)

    {

        int t=arr[N-1];

  

        for(int i=N-1;i>0;i--)

            arr[i]=arr[i-1];  //右移

  

        arr[0]=t;

    }

  }

  很明显,如此代码段,还是比较费力的,我们完全有更快的办法。下面是一个杂技算法,时间复杂度大约O(t* t),,高人算一下,本人估算不太准确(这个和希尔排序有点像,我不太会算)。算法如下:

  

   首先,要先用欧几里得算法求最大公约数:

   int gcd(int i,int j)

   {

      while(i!=j)

      {

         if(i>j)

            i-=j;

         else

            j-=i;

    

         return i;

       }

   }

   这个时间复杂度是O(logN)。虽然算法比较慢,但是也够用了。

   杂技算法如下:

   for(int i=0;i<gcd(rotdist,n);i++)

   {

       t=x[i];

       j=i;

       while(1)

       {

          int k=j+rotdist;

          if(k>=n)

              k-=n;

          if(k==i)

              break;

          

          x[j]=x[k];

          j=k;

        }

        x[j]=t;

  }

  算法的基本思想就是将字符串想象成为了一个标准环路,结果,依次将x[i]移动 rotdist个位置,一直到最后。这样逐次移动每个字符串,一共移动 gcd次。大大减少了移动次数。但是速度还是很慢。还有更高速的移动方法。

  

   

抱歉!评论已关闭.