数组旋转中的超时问题。这个解决方案的速度有多慢?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数组旋转中的超时问题。这个解决方案的速度有多慢?相关的知识,希望对你有一定的参考价值。

我正在做一个关于Hackerrank的问题,该问题应该通过一定数量的旋转来移动数组。例如:

1 2 3 4 5 -> 2 3 4 5 1

经过一次轮换。这将在测试用例要求的情况下多次完成。

这是我的代码:

    using System;
    using System.Collections.Generic;
    using System.IO;
    class Solution {
        static void Main(String[] args) {
            /* Enter your code here. Read input from STDIN. Print output to STDOUT. Your class should be named Solution */
            string[] firstLine = Console.ReadLine().Split(' ');     
            int numInts = Convert.ToInt32(firstLine[0]);               //Number of ints in list
            int rotations = Convert.ToInt32(firstLine[1]);             //number of left rotations
            int[] numList = Array.ConvertAll(Console.ReadLine().Split(' '), int.Parse);    //the list to rotate

            for(int i = 0; i < rotations; i++){
                int[] newArray = new int[numList.Length];
                Array.Copy(numList, 1, newArray, 0, numList.Length-1);           //copy from index 1 to end
                newArray[numList.Length-1] =  numList[0];               //end should equal first elem in old array
                Array.Copy(newArray, numList, numList.Length);
            }


            foreach(var i in numList){
                Console.Write(i + " ");
            }
        }
    }

我正在通过几乎所有的测试,但是在最后的2上遇到超时问题。我想出的这个解决方案到底有多慢?

如果您想了解更多信息,请访问以下链接:https://www.hackerrank.com/challenges/array-left-rotation/problem

答案

您应该意识到,如果您从索引n开始读取数组,则意味着它已经旋转了n%长度的时间。考虑到这种推断,您的整个程序可以简化为

  using System;
  using System.Collections.Generic;
  using System.IO;

  class Solution 
  {
      static void Main(String[] args) 
      {
            string[] firstLine = Console.ReadLine().Split(' ');     
            int numInts = Convert.ToInt32(firstLine[0]);               //Number of ints in list
            int rotations = Convert.ToInt32(firstLine[1]);             //number of left rotations
            int[] numList = Array.ConvertAll(Console.ReadLine().Split(' '), int.Parse);    //the list to rotate

           for( var i = 0 ; i < numInts ; ++i )
               Console.WriteLine( numList [ (i + rotations) % numInts ] );
        }
    }
另一答案

你有太多的数组副本,这需要时间。我认为开头的int.parse也是不必要的。你不应该在每次旋转后逐字地创建数组的副本,而是在最后一次旋转后计算每个元素的位置(计算多少步)

这是示例工作解决方案:

int rotations = 22222222;             //number of left rotations
string[] numList = "5 1 2 4 3".Split(' ');    //the list to rotate

var index = rotations % numInts;
var indexesToWrite = Enumerable.Range(index, numInts - index).Concat(Enumerable.Range(0, index));

foreach (var indexToWrite in indexesToWrite)
{
    Console.Write(numList.ElementAt(indexToWrite) + " ");
}

为了澄清代码 - 很明显(正如其他人注意到的那样)我们旋转后的每个[numInts]时间都会回到星形状态。所以这显然导致我们得出一个结论,即分裂后的剩余部分至关重要。之后,我们必须决定%运算符的结果。实际上,这是从哪里开始(数组的索引)“读取”numList数组的信息。在我们到达表的末尾之后,我们应该从numList数组的开头(index = 0)读取,直到我们开始读取的索引。

另一答案
     - Array a has n number of elements
     - d variable used for number of left rotations


    static int[] rotLeft(int[] a, int d) {
                int l = a.Length, c = 0;
// if the array length is same as number of rotations not need to rotate the array. //we can return the same array as end result would be same
                if( l == d)
                    return a;
// if array length is less the no of rotations, Here I am finding the reminder as //we can skip the l ( length of the array ) rotations as l rotations will give you the same array. //Now just rotate it to the new value d rotations to get the end result.              
                if ( l < d) 
                    d = d % l;


                int[] copy = new int[a.Length];
    //In first loop I am copying values of array "a" from d to end of the array
                for(int j=d; j< a.Length; j++)
                {
                    copy[c] = a[j];
                    c++;
                }
    // Here I am appending the copy array values form 0 to start no of rotations
                for(int i=0;i < d; i++ )
                {
                    copy[c]= a[i];
                    c++;
                }
                // End result would be the result
                return copy;
            }

以上是关于数组旋转中的超时问题。这个解决方案的速度有多慢?的主要内容,如果未能解决你的问题,请参考以下文章

让 CPU 告诉你硬盘和网络到底有多慢

[CNBETA]动图告诉你 光速到底有多慢?

DISTINCT 有多慢?

VB6求教 listview和数组的使用

查找数组字段不为空的 MongoDB 记录

查找数组字段不为空的 MongoDB 记录