在保持顺序的同时对数组中的偶数和奇数进行排序

时间:2017-02-18 12:30:06

标签: arrays algorithm sorting partition

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}

编辑:如果在没有额外空间的情况下无法实现,那么它是否可以使用仅重新排列的整数?因为交换只能在数组中出现

3 个答案:

答案 0 :(得分:2)

我认为这是不太可能的,因为没有额外的空间(取决于n)你必须交换元素,从而使它们混乱(或者你可以在阵列中移动块,但是可能需要非线性的总时间;据我所知,在问题中不允许使用链接列表等其他数据结构。

此问题可以视为稳定的就地非比较排序,其中所有偶数元素都映射到零,并且所有奇数元素都映射到一个用于比较,并且似乎没有符合这些条件的算法(稳定,时间O(n),额外记忆O(1))(参见例如"非比较排序"表格https://en.wikipedia.org/wiki/Sorting_algorithm#Comparison_of_algorithms)。

答案 1 :(得分:0)

是的,有可能。这个想法是先计算总数,再将奇数一一移到正确的位置。

    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++;
        }
    }
}

答案 2 :(得分:0)

这是我的解决方案:


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] + " ");
    }

}