Algorithm 在给定数组索引后移动k个数组元素

Algorithm 在给定数组索引后移动k个数组元素,algorithm,language-agnostic,Algorithm,Language Agnostic,初始数组:22334278914263060 k=3 从索引i=1开始,我们必须移动k个元素,以便它们出现在数组中的元素26之后(即givenIndex=6之后) 最终数组:28914263427300 我们不允许使用额外的空间 我的做法: count = 0; while(count < k) { count++; temp = arr[i]; shift all elements from (i+1) to givenIndex to their im

初始数组:
22334278914263060

k=3

从索引i=1开始,我们必须移动k个元素,以便它们出现在数组中的元素26之后(即givenIndex=6之后)

最终数组:
28914263427300

我们不允许使用额外的空间

我的做法:

count = 0;   
while(count < k)  
{  
  count++;  
  temp = arr[i];  
  shift all elements from (i+1) to givenIndex to their immediate left position;  
  arr[givenIndex] = temp;  
}
count=0;
while(计数
第一次迭代:
temp=23

将所有元素从[i+1](即索引=2)到给定索引(即索引=6)依次向左移动
移位后的数组:
234 27 89 14 26 26 30 60

arr[givinindex]=温度
应用此操作后的数组:
2 34 27 89 14 26 23 30 60

类似地
第二次迭代后的数组:
2 27 89 14 26 23 34 30 60

第三次迭代后的数组:
2 89 14 26 23 34 27 30 60

最坏情况复杂度O(n*k),其中n是数组中的元素数

我们能解决O(n)中的问题吗?

这个旋转可以使用
reverse()
helper函数在线性时间内完成。假设
reverse(x,y)
reverse
array[x]…array[y]

reverse(1, 3); // 27 34 23 .. .. ..
reverse(4, 6); // .. .. .. 26 14 89
reverse(1, 6); // 89 14 26 23 34 27

编写线性时间<代码>反转非常简单,甚至可以在您最喜欢的语言库中找到(例如,C++包含“代码> STD::旋转< /COD>和 STD::Reale”)。假设

reverse(x,y)
reverse
array[x]…array[y]

reverse(1, 3); // 27 34 23 .. .. ..
reverse(4, 6); // .. .. .. 26 14 89
reverse(1, 6); // 89 14 26 23 34 27

编写线性时间<代码>反转<代码>很简单,甚至可以在您最喜欢的语言库中找到(例如,C++包含“代码> STD::旋转< /COD>和<代码> STD::反向< /代码>”。

< P>我可以从您的代码(和示例)中看出,我想在块<代码>之后尝试将块<代码> [i,i+k-1 ] /代码>放置。[i+k,给定索引]

如果是这种情况,@blastfull的建议确实会导致在O(n)中有一个解决方案,并且没有额外的空间:

简单地做:

reverse(i,givenIndex)
reverse(i,givenIndex-k)
reverse(givenIndex-k+1,givenIndex)

你得到了你想要的:)

据我从你的代码(和这个例子)中可以看出,我认为你试图把块
[i,i+k-1]
放在块
[i+k,givenIndex]

如果是这种情况,@blastfull的建议确实会导致在O(n)中有一个解决方案,并且没有额外的空间:

简单地做:

reverse(i,givenIndex)
reverse(i,givenIndex-k)
reverse(givenIndex-k+1,givenIndex)

你得到了你想要的:)

这个问题非常令人惊讶
请参见此处要求的答案。如果您正在寻找使用JAVA旋转arraylist的方法,则有一个完整的解决方案。
public static void rotate(List List,int distance)


只需旋转集合(ArrayList或LinkedList…)

它的参数是一个
列表
(在你的例子中是
数组列表
)和一个
距离
(在你的例子中是
k
)。你看到相似之处了吗?简单地使用它。

这个问题非常令人惊讶
请参见此处要求的答案。如果您正在寻找使用JAVA旋转arraylist的方法,则有一个完整的解决方案。
public static void rotate(List List,int distance)


只需旋转集合(ArrayList或LinkedList…)

它的参数是
列表
(在您的情况下是
数组列表
)和
距离
(在您的情况下是
k
).你看到相似之处了吗?就用这个吧。

什么?移位是怎么发生的?请你再解释一下。不太清楚。从我的观点来看,我看到一些数字被交换了。我们是否必须保留顺序?@MatinKh我编辑了这个问题。我希望现在清楚了。我们可以使用临时变量。但是我们不允许使用与被交换的元素数量成比例的空间。也就是说,在我的问题中提到的例子中,我们不能使用额外的空间O(k),其中k是我们必须移动的元素数量。因为存在“k”旋转,所以它应该是O(n*k).对吗?或者我还是遗漏了什么?等等……什么?转移是怎么发生的?请你再解释一下。不太清楚。在我看来,我看到一些数字交换了。我们是否必须保留顺序?@MatinKh我编辑了这个问题。我希望现在已经清楚了。我们可以使用临时变量。但我们不允许使用与被交换的元素数量成比例的空间。例如,在我的问题中提到的示例中,我们不能使用额外的O(k)空间,其中k是我们必须移动的元素数量。因为存在“k”旋转,它将是O(n*k).对吗?或者我还缺少什么?我不认为它提高了时间复杂度。我不认为它提高了时间复杂度。Java方法对大列表使用
3反向
算法。描述中甚至提到了Jon Bentley的编程珍珠,我是在那里第一次学习该算法的。确实如此。所以?找到解决方案n他也必须学习算法。但是如果他使用java,他可以简单地利用使用它的旋转。java方法对大列表使用
3反向
算法。描述中甚至提到了Jon Bentley的编程珍珠,我是在那里第一次学习算法的。确实如此。那么?为了找到解决方案,他但是如果他使用java,他可以简单地利用使用java的旋转。