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