Java算法:分离奇数偶数(时空复杂度)

时间:2016-04-25 14:19:02

标签: java algorithm

我正在编写一个方法来隔离整数数组,以便所有偶数整数都在数组中的所有奇数整数之前。它必须采用数组O(n)大小的线性时间,并且只需要一定量的额外空间就可以运行。

输入:{2,4,7,6,1,3,5,4} 输出:2,4,6,4,7,1,3,5

输入:{5,12,3,21,8,7,19,102,201}
输出:12,8,102,5,3,21,7,19,201

这些是我的解决方案:

private static void segregateArray1(final int[] arr) {
    if (arr != null) {
        int leftIdx = 0;
        int rightIdx = arr.length - 1;

        while (leftIdx < rightIdx) {
            if (arr[leftIdx] % 2 != 0 && arr[rightIdx] % 2 == 0) {
                // swap immediately
                int temp = arr[leftIdx];
                arr[leftIdx] = arr[rightIdx];
                arr[rightIdx] = temp;
                leftIdx++;
                rightIdx--;
            } else {
                if (arr[leftIdx] % 2 == 0) {
                    leftIdx++;
                }
                if (arr[rightIdx] % 2 == 1) {
                    rightIdx--;
                }
            }
        }
    }
}

方法1采用O(n)并且不占用额外空间。但是,它没有维持秩序。

private static int[] segregateArray2(final int[] arr) {
    List<Integer> evenArr = new ArrayList<Integer>();
    List<Integer> oddArr = new ArrayList<Integer>();

    for (int i : arr) {
        if (i % 2 == 0) {
            evenArr.add(i);
        } else {
            oddArr.add(i);
        }
    }
    evenArr.addAll(oddArr);

    return ArrayUtils.toPrimitive(evenArr.toArray(new Integer[0]));
}

方法2创建ArrayList。我不确定这是否也是O(n)。

测试:

public static void main(String[] args) {
    int[] arr = {2, 4, 7, 6, 1, 3, 5, 4};
    segregateArray1(arr);
    System.out.println(Arrays.toString(arr));

    int[] arr = {2, 4, 7, 6, 1, 3, 5, 4};
    // creates another array segragatedArr!
    int[] segragatedArr = segregateArray2(arr);
    System.out.println(Arrays.toString(segragatedArr));
}

我不确定是否有更简洁的解决方案/简单性来满足时空复杂度(O(n)和空间约束)。

2 个答案:

答案 0 :(得分:0)

最简单的方法是保持相同的时间复杂度,并且输出数组的大小与输入数组的大小相同,是对每个值进行模数检查,如果是正数则放置到数组的前面,如果是负数,那么到后面。请记住,您需要两个变量来了解正数和负数的下一个可用位置

答案 1 :(得分:-1)

ArrayList numberList = new ArrayList<>(Arrays.asList(1,2,3,4,5,6)); numberList.stream().filter(i -> i % 2 == 0).forEach(System.out::println);