简体   繁体   English

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

[英]Java Algorithm: Segregate Odd Even Numbers (time-space complexity)

I am writing a method that segregates the array of integers so that all the even integers precede all the odd integers in the array.我正在编写一种隔离整数数组的方法,以便所有偶数整数先于数组中的所有奇数整数。 It must take linear time in the size of the array O(n) and operate in place with only a constant amount of extra space.它必须在数组O(n)的大小上花费线性时间,并且只需要恒定量的额外空间就位操作。

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

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

These were my solutions:这些是我的解决方案:

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

Method 1 takes O(n) and does not take up extra space.方法一占用O(n),不占用额外空间。 However, it does not maintain order.但是,它不维护秩序。

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

Method 2 creates ArrayList.方法 2 创建 ArrayList。 I am unsure if this is also O(n).我不确定这是否也是 O(n)。

To test:测试:

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

I am not sure if there is a neater solution/simplicity which satisfies time-space complexity (O(n) and space constraint).我不确定是否有一个更简洁的解决方案/简单性可以满足时空复杂度(O(n)和空间约束)。

The simplest way to do this and keep the same time complexity and also that the size of the output array is the same size as the input array is to do a modulus check on each value and if it is positive that placed to to the front of the array and if negative then to the back.做到这一点并保持相同的时间复杂度并且输出数组的大小与输入数组的大小相同的最简单方法是对每个值进行模数检查,如果它是正数,则放在前面数组,如果为负,则到后面。 Please keep in mind that you will need two variables to know the next available locations for the positive and negative numbers请记住,您需要两个变量才能知道正数和负数的下一个可用位置

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM