简体   繁体   中英

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.

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

Input: {5, 12, 3, 21, 8, 7, 19, 102, 201}
Output: 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. 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. I am unsure if this is also 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).

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)); numberList.stream().filter(i -> i % 2 == 0).forEach(System.out::println);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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