Reputation: 855
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--;
}
}
}
Upvotes: 1
Views: 2186
Reputation: 21
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;
}
}
Upvotes: 1
Reputation: 133995
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;
}
Upvotes: 3
Reputation: 2715
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.
Upvotes: 0
Reputation: 8095
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.
Upvotes: 0