【问题标题】:Segregate Even and Odd numbers In an Integer Array using Recursion使用递归分离整数数组中的偶数和奇数
【发布时间】:2014-09-30 03:06:41
【问题描述】:

我正在做一个算法练习,它要求重新排列一个整数数组,将所有偶值元素放在奇值元素之前。

想了想,想出了如下伪代码:

int[] Rearrange(int [] arr)
{

   if arr.length=1
     return arr;

   if arr[0] is even
    return arr[0] followed by Rearrange(arr.subarray(1,arr.length))
   else
    return Rearrange(arr.subarray(1,arr.length)) followed by arr[0]

}

我有点担心我上面提出的解决方案,因为我需要在每个递归周期中进行复制操作,这很昂贵。请高手指教,谢谢!

【问题讨论】:

  • 你的解决方案永远不会递归。
  • @BobJarvis 这是伪代码,所以我在做假设,但它确实看起来像是递归给我。 Rearrange 基金在第二个 if 语句的两个分支中调用自己:首先如果 arr[0] 是偶数,在 else 情况下也是如此。这是对递归的不好使用。
  • @DuncanC - 自从我发表我的原始评论以来,该问题已被编辑以显示对Rearrange 的调用。

标签: arrays algorithm recursion


【解决方案1】:

递归很昂贵,而且您的方法会产生大量额外的副本。有时递归会产生一个优雅的解决方案,而其他时候它绝对是适合这项工作的错误工具。这是一个错误的工作案例工具。

相反,编写一个保留头索引和尾索引的方法。将头指针初始化为数组的开头,将尾索引初始化为结尾。

每次遍历时,循环遍历列表头部的项目,寻找奇数。当你找到一个时,停下来,然后从最后寻找一个偶数,向后看。当你找到一个时,切换两个值(使用第三个 int 作为临时存储)。永远重复。当头部和尾部索引相遇时,您就完成了。

类似这样的:

int head_index = 0;
int tail_index = array.count;
int temp;
while (true)
{
  //Find the next odd number at the front of the array.
  while (array[head_index] %2==0) && head_index < tail_index)
    head_index++;

  //Find the next even number at the end of the array.
  while (array[tail_index]%2==1 && head_index < tail_index)
    tail_index--;

  //If the pointers meet, we're done
  if (head_index <= tail_index)
    break;

  //Swap the items at the current indexes
  temp = array[head_index];
  array[head_index] = array[tail_index];
  array[tail_index] = temp;
}

(完全未经测试,我很累,但基本想法应该可行)

它或多或少是 C 语法伪代码。

它应该在 O(n) 时间内运行,唯一需要的额外 RAM 是您的 2 个索引和临时保存变量。

【讨论】:

    【解决方案2】:

    即使问题已得到解答,我仍将解决此问题的递归版本放在这里,以便好奇的人可以了解为什么递归对于此问题来说是一种不好的方法。

    public static int[] segregate(int[] array, int left) {
    
        int leftIndex = left;
    
        if(left == array.length) {
            return array;
        }
    
        for(int i = leftIndex + 1; i < array.length; i++) {
            if(array[leftIndex] % 2 == 1) {
                if(array[i] % 2 == 0) {
                    int temp = array[leftIndex];
                    array[leftIndex] = array[i];
                    array[i] = temp;
                }
            }
        }
    
        return segregate(array, leftIndex + 1);
    }
    

    从代码中可以看出,该方法会调用自己N次。当您考虑到方法中 for 循环的复杂度为 O(N) 的事实时,递归的总复杂度将为 O(n*2),这比非递归解决方案更差。

    【讨论】:

      猜你喜欢
      • 2018-09-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-20
      • 1970-01-01
      • 2013-02-02
      • 2014-08-31
      • 1970-01-01
      相关资源
      最近更新 更多