Arrays 在不到O(n)的时间内反转数组的子数组

Arrays 在不到O(n)的时间内反转数组的子数组,arrays,algorithm,linked-list,reverse,Arrays,Algorithm,Linked List,Reverse,我们如何在不到O(n)的时间内反转数组(或任何其他数据结构,如链表(不是双重的))的子数组(例如从第i个索引到第j个索引)?O(n)的时间消耗很小。(我想在数组上进行多次反转,比如从头开始反转n次(每次,向前一个指数,然后再反转),所以应该有一种方法,它的摊销分析会让我们的时间消耗小于O(n),知道吗? 提前感谢:)我想你想用错误的方法来解决这个问题。我猜你想从整体上改进算法,而不是O(n)反转的东西。因为那是不可能的。如果你必须考虑每个n个元素,你总是有O(n)。< /P> 正如我所说,你能做

我们如何在不到O(n)的时间内反转数组(或任何其他数据结构,如链表(不是双重的))的子数组(例如从第i个索引到第j个索引)?O(n)的时间消耗很小。(我想在数组上进行多次反转,比如从头开始反转n次(每次,向前一个指数,然后再反转),所以应该有一种方法,它的摊销分析会让我们的时间消耗小于O(n),知道吗?

提前感谢:)

我想你想用错误的方法来解决这个问题。我猜你想从整体上改进算法,而不是O(n)反转的东西。因为那是不可能的。如果你必须考虑每个n个元素,你总是有O(n)。< /P> 正如我所说,你能做的就是改进O(n^2)算法。你可以用O(n)来解决这个问题: 假设我们有以下列表:

a b c d e
然后使用算法修改此列表:

e d c b a
e a b c d
等等。。最后,你会发现:

e a d b c
如果有两个指针来自数组两端,并且在指针之间交替(递增/递减/获取值),则可以获得此列表。这给了你整个过程的O(n)

此算法的更详细说明:

e d c b a
e a b c d
使用上一个列表,我们希望元素的顺序如下:

a b c d e
2 4 5 3 1
所以你创建了两个指针。一个指向列表的开头,另一个指向列表的结尾:

a b c d e
^       ^
p1      p2
然后,算法的工作原理如下:

1. Take the value of p2
2. Take the value of p1
3. Move the pointer p2 one index back
4. Move the pointer p1 one index further
5. If they point to the same location, take the value of p1 and stop.
   or if p1 has passed p2 then stop.
   or else go to 1.

我认为你想用错误的方法来解决这个问题。我猜你想从整体上改进算法,而不是O(n)反转的东西。因为那是不可能的。如果你必须考虑每个n个元素,你总是有O(n)。< /P> 正如我所说,你能做的就是改进O(n^2)算法。你可以用O(n)来解决这个问题: 假设我们有以下列表:

a b c d e
然后使用算法修改此列表:

e d c b a
e a b c d
等等。。最后,你会发现:

e a d b c
如果有两个指针来自数组两端,并且在指针之间交替(递增/递减/获取值),则可以获得此列表。这给了你整个过程的O(n)

此算法的更详细说明:

e d c b a
e a b c d
使用上一个列表,我们希望元素的顺序如下:

a b c d e
2 4 5 3 1
所以你创建了两个指针。一个指向列表的开头,另一个指向列表的结尾:

a b c d e
^       ^
p1      p2
然后,算法的工作原理如下:

1. Take the value of p2
2. Take the value of p1
3. Move the pointer p2 one index back
4. Move the pointer p1 one index further
5. If they point to the same location, take the value of p1 and stop.
   or if p1 has passed p2 then stop.
   or else go to 1.
正如duedl0r提到的,O(n)是你的最小值。您必须将n个项目移动到其新位置

既然你提到了一个链表,这里有一个O(n)解决方案

如果移动所有节点并反转其方向,然后将端点与列表的其余部分绑定,则子列表将反转。因此:

1->2->3->4->5->6->7->8->9
从4到7的倒转将改变:

4->5->6->7
进入:

也就是O(n+1+1+1+m*(1+1+1)+1+1+1)。 如果没有大O中不允许的所有数字,那就是O(n+m),可以称为O(n+n),也可以称为O(2n)

这就是O(n)。

正如duedl0r提到的,O(n)是你的最小值。您必须将n个项目移动到其新位置

既然你提到了一个链表,这里有一个O(n)解决方案

如果移动所有节点并反转其方向,然后将端点与列表的其余部分绑定,则子列表将反转。因此:

1->2->3->4->5->6->7->8->9
从4到7的倒转将改变:

4->5->6->7
进入:

也就是O(n+1+1+1+m*(1+1+1)+1+1+1)。 如果没有大O中不允许的所有数字,那就是O(n+m),可以称为O(n+n),也可以称为O(2n)

这就是O(n)。

对于给定的数组,您可以在O(n)时间内完成。这里l表示起始索引,r表示结束。所以我们需要将子阵列从r反转到l

public void reverse(int[] arr, int l, int r)
  {
      int d = (r-l+1)/2;
      for(int i=0;i<d;i++)
      {
         int t = arr[l+i];
         arr[l+i] = arr[r-i];
         arr[r-i] = t;
      }
    // print array here 
  }
public void reverse(int[]arr,int l,int r)
{
int d=(r-l+1)/2;
对于(inti=0;i可以对给定的数组执行O(n)次。这里l表示开始索引,r表示结束。所以我们需要将子数组从r反转到l

public void reverse(int[] arr, int l, int r)
  {
      int d = (r-l+1)/2;
      for(int i=0;i<d;i++)
      {
         int t = arr[l+i];
         arr[l+i] = arr[r-i];
         arr[r-i] = t;
      }
    // print array here 
  }
public void reverse(int[]arr,int l,int r)
{
int d=(r-l+1)/2;

对于(int i=0;iYes,但我没有要求代码,实际上我是通过O(n)来做的,出于好奇寻找更好的解决方案:)我想这没关系,不是吗?是的,问也没问题,但作业任务应该被标记为这样。你试图通过所有这些反转实现的最终目标是什么?不要把我们放在“盒子”中,我们将有更好的机会进行一些开箱思考;)@Branko:这真是一项很长的任务,相信我,我所要求的甚至与我必须做的事情都不接近:(我只是想改进我的最终算法的时间消耗,它使用这个任务(反转)来操作。用O(1)找到解决方案)我的答案是肯定的,但我没有要求代码,事实上我是通过O(n)来做的,出于好奇寻找更好的解决方案:)我想这没关系,不是吗?是的,问也没问题,但家庭作业任务应该被标记为这样。你通过所有这些反向操作试图实现的最终目标是什么?不要把我们放在一个“盒子”里,我们将有更好的机会进行一些开箱思考;)@Branko:这真是一项很长的任务,相信我,我所要求的甚至与我必须做的事情都不接近:(我只是想改进我的最终算法的时间消耗,它使用这个任务(反转)来操作。用O(1)找到解决方案)请看我的答案:是的,改进O(n^2)算法是我想要的,但是你能解释一下指针之间的交替是什么吗?谢谢你,印象深刻:)这只是我试图达到的算法,谢谢你的帮助。:是的,改进O(n^2)算法是我想要的,但是你能解释一下指针之间的交替是什么吗?谢谢,印象深刻:)这正是我想要的算法,谢谢你的帮助。