如何解决旋转数组k
给出一个数组和一个数字k,我们必须将数组旋转k次。
Sample Input
1 //number of of testcases
5 2 //5(array size) 2(K value)
1 2 3 4 5 /array elements
Sample output
4 5 1 2 3
这是我的代码
import java.util.*;
class TestClass {
public static void main(String args[] ) throws Exception {
// Write your code here
Scanner input=new Scanner(System.in);
int testcases=input.nextInt();
for(int i=0;i<testcases;i++)
{
int size=input.nextInt();
int rotationNo=input.nextInt();
rotateArray(size,rotationNo,input);
}
}
public static void rotateArray(int size,int rotationNo,Scanner input)
{
int[] arr=new int[size];
int[] result=new int[size];
rotationNo=rotationNo%size;
for(int i=0;i<size;i++)
{
arr[i]=input.nextInt();
}
int resultIndex=0;
int index=size-rotationNo;
int k=index,t=0,track=0;
while(true)
{
if(k<size)
{
System.out.print(arr[k++]+" ");
++track;
if(track==size)
{
break;
}
else
{
continue;
}
}
if(t<index)
{
if(t==(index-1))
{
System.out.print(arr[t++]);
}
else
{
System.out.print(arr[t++]+" ");
}
++track;
if(track==size)
{
break;
}
else
{
continue;
}
}
}
System.out.println();
}
}
这个问题是在编程比赛中提出的。我的所有测试用例都通过了,但其中一个显示超出了时间限制。但是我不明白超过期限的原因是什么。无论测试用例如何,循环总是会停止。 我的代码的时间复杂度为O(n)。 是否还有另一个更好,更有效的解决方案?
解决方法
一旦读取并存储了k个值,便开始直接输出输入(即不存储它)。 然后输出最初读取并存储的k个值。
数组内部的移位是此处的相关操作。
进行的移位越少(如果正确实施,移位的距离在这里就没有太大关系),效果越好。它包括存储到数组或从数组中检索。我认为读取和输出(如果进行之间没有任何处理的话)可以忽略不计。即我专注于转变。
严格来说,读取和输出是处理过程,这意味着无法计算O()的改进。
但是让我忽略对改进的O()估计的读取和输出:
建议的建议将在从O(n)转换为O(k)的过程中改善数组访问的数量。诚然,此处忽略了读取和输出。在这里避免了从数组的存储和检索,尤其是避免了数组内部的移位,而这就是与O(k)部分相关的内容。
因此,相关运算为O(k),而忽略O(1)中的n-k个值。
类似的测试用例
1
10000 1
1 2 3 4 5 6 7 8 ...
将轻松消除在读后输出之前执行O(4*10000)
的程序,即存储所有内容,读取和写入所有内容以进行移位,然后读取所有内容以进行输出。与O(2*1)
相比,仅存储单个值并再次读取以最终输出。
(是的,我知道干净的O()分析不会使用因子或任何数字。我希望您能理解这一点;;-)
这是一个代码建议(简化为单个测试用例):
import java.util.*;
public class Test {
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
int testcases= input.nextInt(); //ignored,assuming 1
int size = input.nextInt();
int rotation = input.nextInt();
int i=0;
int[] newArr = new int[rotation%size]; //small array
// based on the nice idea by User-Upvotedon'tsayThanks
for(; i<rotation%size; i++)
{
newArr[i] = input.nextInt(); // few write accesses
}
for(; i<size; i++)
{
System.out.println( input.nextInt()); //many direct outpots
}
for(i=0; i<rotation%size; i++)
{
System.out.println(newArr[i]); // few outputs from array
}
return;
}
}
输入以下内容:
1
5 2
1 2 3 4 5
它为您提供以下输出:
3
4
5
1
2
与模数输入相同的输出:
1
5 7
1 2 3 4 5
,
我提供了一个解决方案,在该解决方案之下,将直接输出扫描仪输入,直到满足输入大小为止。它具有恒定的输入时间o(n),但是仅触摸每个项目一次。并避免使用while循环,否则可能会增加迭代的乘数。
public class Test {
public static void main(String[] args) {
int rotation = new Scanner(System.in).nextInt();
int size = new Scanner(System.in).nextInt();
int[] values = rotate(rotation,size,new Scanner(System.in));
for(int i : values){
System.out.println(i);
}
}
public static int[] rotate(int rotation,int size,Scanner input){
int[] newArr = new int[size];
for(int i = 0; i<size; i++){
int newPosition = i + rotation;
newPosition = newPosition >= size ? newPosition - size : newPosition;
newArr[newPosition] = input.nextInt();
}
return newArr;
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。