简体   繁体   中英

Sort even and odd numbers in order

I am trying to segregate even and odd numbers to left and right respectively on one pass. Also, I want to ensure that these numbers are sorted in asc order such a way entire logic will have a complexity of O(n).

For example if my input is {9,8,2,3,11,10,1};

This logic I implemented o/p as {10 8 2 3 11 9 1 } but I want to ensure my output is sorted as { 2,8,10,1,3,9,11} in same one pass.

static void segregateEvenOdd(int arr[]) {
    /* Initialize left and right indexes */
    int left = 0, right = arr.length - 1;
    while (left < right) {
        /* Increment left index while we see 0 at left */
        while (arr[left] % 2 == 0 && left < right)
            left++;

        /* Decrement right index while we see 1 at right */
        while (arr[right] % 2 == 1 && left < right)
            right--;

        if (left < right) {
            /* Swap arr[left] and arr[right] */
            int temp = arr[left];
            arr[left] = arr[right];
            arr[right] = temp;
            left++;
            right--;
        }
    }
}

Use the Sort overload that lets you pass a Comparator . The comparison function should be something like below (pseudocode):

Comparison(a, b)
{
    if (Even(a) && !Even(b))
        return -1; // a < b
    if (Even(b) && !Even(a))
        return 1; // a > b
    // both are even, or both are odd.
    if (a < b) return -1;
    if (a > b) return 1;
    return 0;
}

You could also use a list:

List<Integer> list = Arrays.asList(yourArray);
Collections.sort(list, new Comparator<Integer>() {
       public int compare(Integer a, Integer b) {
                return a%2 - b%2;
       }
}

I am trying to segregate even and odd numbers to left and right respectively on one pass. Also, I want to ensure that these numbers are sorted in asc order such a way entire logic will have a complexity of O(n).

For example if my input is {9,8,2,3,11,10,1};

This logic I implemented o/p as {10 8 2 3 11 9 1 } but I want to ensure my output is sorted as { 2,8,10,1,3,9,11} in same one pass.

static void segregateEvenOdd(int arr[]) {
    /* Initialize left and right indexes */
    int left = 0, right = arr.length - 1;
    while (left < right) {
        /* Increment left index while we see 0 at left */
        while (arr[left] % 2 == 0 && left < right)
            left++;

        /* Decrement right index while we see 1 at right */
        while (arr[right] % 2 == 1 && left < right)
            right--;

        if (left < right) {
            /* Swap arr[left] and arr[right] */
            int temp = arr[left];
            arr[left] = arr[right];
            arr[right] = temp;
            left++;
            right--;
        }
    }
}

This isn't possible in one pass. You really have two separate sorts going on. one for even number and one for odds.

Here is what I would propose.

Solution 1.

if you are allowed to introduce new data structures take the following approach create two ArrayList (one for even one for odd) separate them appropriately. Run Collections.Sort on both. Repopulate your initial array iterativly.

Solution 2.

Use the method you have above to properly separate evens and odds. Count number of evens in list. Build a typical sorting routine like mergesort and call the routine on the two different segments of your array. above example would be called like

merge(arr, 0, 2);
merge(arr, 3, 6);

Both of these solutions have overall Time complexity: O(nlogn). Space complexity: O(n). Solution one is easier to implement but solution two allows you to do a more in-place sort. Other sorting routines have best case O(n) time but don't guarantee it.

I would use a quicksort or any of the other standard algorithms, but define the comparison between elements as: a is less than b if a is even and b is odd or they are both even or odd and a<b .

This will not give you O(n), that's not possible, but will max performance by reusing well known algorithms.

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