【问题标题】:Sort Even and Odd numbers in array while maintaining order在保持顺序的同时对数组中的偶数和奇数进行排序
【发布时间】:2017-07-07 23:54:38
【问题描述】:

http://www.geeksforgeeks.org/segregate-even-and-odd-numbers/我在查找面试问题时遇到了这个有趣的问题。该算法看起来很简单,但我想知道是否可以在不使用任何额外空间的情况下保持偶数和奇数的顺序,同时仍然保持 O(n) 的时间复杂度。

例如

输入:{12、34、45、9、8、90、3}

输出:{12、34、8、90、45、9、3}

编辑:如果没有额外的空间是不可能的,它可以与仅重新排列的整数一起工作吗?由于交换只能发生在数组中

【问题讨论】:

  • “不使用任何额外空间”是什么意思。即使您提到的代码也使用了额外的空间(leftright)。您的意思是“仅使用 O(1) 空间”
  • 不使用任何其他数组,将偶数存储在一个数组中,将奇数存储在另一个数组中,然后将它们组合起来,问题就很简单了。
  • 好的,这意味着只使用常量空间。

标签: arrays algorithm sorting partition


【解决方案1】:

我认为这不太可能,因为如果没有额外的空间(取决于 n),您将不得不交换元素并因此打乱它们(或者您可以移动数组中的块,但这可能需要非线性整体时间; 据我了解,问题中不允许使用其他数据结构(如链表)。

这个问题可以被视为稳定的就地非比较排序,其中所有偶数元素都映射到零,所有奇数元素都映射到一以进行比较,似乎没有符合这些标准的算法(稳定,时间O(n),额外内存O(1))(参见例如https://en.wikipedia.org/wiki/Sorting_algorithm#Comparison_of_algorithms的“非比较排序”表)。

【讨论】:

  • 嗯,那么是否可以使用其他数组作为缓冲区来交换数组?
  • @user2435044:是的,这变得微不足道:您只需将所有偶数复制到主数组的开头,并且(在同一次传递中)将所有赔率复制到缓冲区数组的开头。然后将所有赔率复制回主数组,从复制偶数的末尾开始。 (或者这不算作“交换 [ping] 数组到位”?我不确定你所说的那个短语的确切含义,因为使用其他数组似乎暗示你 not i> 就地交换。)
  • 哦,抱歉,我的意思是使用另一个数组来存储偶数/赔率的位置以保留顺序。我正在考虑做一种计数排序的变体来实现这一点,但是在尝试保留订单时会变得有点混乱
  • 这应该还是很简单的:在一次通过中,您可以填充偶数应该结束的位置的详细信息,然后在单独的通过中填充赔率应该结束的位置的详细信息。然后将它们交换到位,确保更新位置数组以“清除”已移动到正确位置的条目(例如,将它们设置为 -1)。
  • 交换最终会不会改变足够的时间复杂度而不是 O(n)?
【解决方案2】:

是的,这是可能的。思路是先统计总偶数,然后将奇数一个一个移动到正确的位置。

    public void segregateEvenOddWithOrder(int[] arr) {
    int countEven = 0;
    int length = arr.length;
    for (int i = 0; i < length; i++) {
        if (arr[i]%2 == 0){
            countEven++;
        }
    }
    int i = 0;
    int j = i+1;
    while (i != countEven){
        if (arr[i]%2 == 0){
            i++;
            j = i + 1;
        }else if (arr[i]%2 == 1 && j < length){
            int temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
            j++;
        }
    }
}

【讨论】:

    【解决方案3】:

    这是我的解决方案:


    public static void segregateEvenOdd_Sorted_Optimized(int[] arr, int n) {

        List<Integer> evenNums = new ArrayList<>();
        List<Integer> oddNums = new ArrayList<>();
    
        for (int i = 0; i < n; i++) {
    
            if (arr[i] % 2 == 0) {
                evenNums.add(arr[i]);
            }
            if (arr[i] % 2 == 1) {
                oddNums.add(arr[i]);
            }
    
        }
    
        Collections.sort(evenNums);
        Collections.sort(oddNums);
    
        for (int i = 0; i < evenNums.size() + oddNums.size(); i++) {
            if (i < evenNums.size()) {
                arr[i] = evenNums.get(i);
            } else {
                arr[i] = oddNums.get(i - evenNums.size());
            }
    
        }
    
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 2015-10-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多