Reputation: 2436
This is an interview question.
There are some random numbers given (let's say in an integer array).
12 67 1 34 9 78 6 31
6 12 34 78 67 31 9 1
Upvotes: 7
Views: 22170
Reputation: 250
package com.java.util.collection;
import java.util.Arrays;
import java.util.Collections;
public class EvenOddSorting {
public static void eventOddSort(int[] arr) {
int i =0;
int j =arr.length-1;
while(i<j) {
if(isEven(arr[i]) && isOdd(arr[j])) {
i++;
j--;
} else if(!isEven(arr[i]) && !isOdd(arr[j])) {
swap(i,j,arr);
} else if(isEven(arr[i])){
i++;
} else{
j--;
}
}
display(arr);
// even number sorting
Arrays.sort(arr,0,i);
insertionSort(arr,i,arr.length);
// odd number sorting
display(arr);
}
/**
* Instead of insertion sort, you can use merge or quick sort.
* @param arr
* @param firstIndex
* @param lastIndex
*/
public static void insertionSort(int[] arr, int firstIndex, int lastIndex){
for(int i=firstIndex+1;i<lastIndex;i++){
int key =arr[i];
int j=i-1;
while(j>=firstIndex && key > arr[j]) {
arr[j+1] = arr[j];
arr[j] =key;
j=j-1;
}
System.out.println("\nAfter "+(i+1) +" Iteration : ");
display(arr);
}
}
public static void display(int[] arr) {
System.out.println("\n");
for(int val:arr){
System.out.print(val +" ");
}
}
private static void swap(int pos1, int pos2, int[] arr) {
int temp = arr[pos1];
arr[pos1]= arr[pos2];
arr[pos2]= temp;
}
public static boolean isOdd(int i) {
return (i & 1) != 0;
}
public static boolean isEven(int i) {
return (i & 1) == 0;
}
public static void main(String[] args) {
int arr[]={12, 67, 1, 34, 9, 78, 6, 31};
eventOddSort(arr);
}
}
Upvotes: 1
Reputation: 1
in Java :- Best Approach, Minimum Complexity
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Scanner;
public class EvenOddSorting {
public static void main(String[] args) {
// TODO Auto-generated method stub
int i, size;
ArrayList<Integer> listEven = new ArrayList<Integer>();
ArrayList<Integer> listOdd = new ArrayList<Integer>();
ArrayList<Integer> finalList = new ArrayList<Integer>();
Scanner sc = new Scanner(System.in);
System.out.println("Enter Array Size : ");
size = sc.nextInt();
int A[] = new int[size];
for (i = 0; i < size; i++) {
A[i] = sc.nextInt();
}
for (i = 0; i < size; i++){
if (A[i] % 2 == 0){
listEven.add(A[i]);
}
else if (A[i] % 2 != 0) {
listOdd.add(A[i]);
}
}
Collections.sort(listEven);
Collections.sort(listOdd);
Collections.reverse(listOdd);
finalList.addAll(listOdd);
finalList.addAll(listEven);
System.out.println("Result is : "+finalList);
}
}
Output :-
Enter Array Size : 10
1 2 3 4 5 6 7 8 9 10 Result is : [9, 7, 5, 3, 1, 2, 4, 6, 8, 10]
Upvotes: -1
Reputation: 11
Here's the code :
@Override
public int compare(Integer o1, Integer o2) {
if (o1 % 2 ==0)
{
if (o2 % 2 == 0)
{
if (o1 < o2)
return -1;
else
return 1;
}
//if (o2 % 2 != 0)
else
{
return -1;
}
}
else
{
if (o2 % 2 != 0)
{
if (o1 < o2)
return 1;
else
return -1;
}
//if (o2 % 2 == 0)
else
{
return 1;
}
}
}
Upvotes: 1
Reputation: 2241
I just coded a fast example, as below:
public class CustomSorting {
public static void main(String[] args) {
Integer[] intArray = new Integer[] {12, 67, 1, 34, 9, 78, 6, 31};
Arrays.sort(intArray, new Comparator() {
@Override
public int compare(Object obj1, Object obj2) {
Integer int1 = (Integer) obj1;
Integer int2 = (Integer) obj2;
int mod1 = Math.abs(int1%2);
int mod2 = Math.abs(int2%2);
return ((mod1 == mod2) ? ((mod1 == 0) ? int1.compareTo(int2) : int2.compareTo(int1)) : ((mod1 < mod2) ? -1 : 1));
}
});
}
}
Output:
[6, 12, 34, 78, 67, 31, 9, 1]
Upvotes: 0
Reputation: 1
Like this:
var list = new List<int>{1,5,2,6,3,9,10,11,12};
var sorted = list.Where (l => l%2 ==0).OrderBy (l=>l).Union(list.Where (l => l%2 != 0).OrderByDescending (l=>l));
Upvotes: 0
Reputation: 726599
Any collection that supports sorting with a custom comparer will do - even an array. Implement your custom comparator as follows:
public int compare(int x, int y) {
if (x&1 == y&1) {
// Both numbers are odd or both numbers are even
if (x&1 == 0) {
// Both numbers are even: compare as usual
return Integer.compare(x, y);
} else {
// Both numbers are odd: compare in reverse
return Integer.compare(y, x);
}
}
// One is odd, the other one is even
if (x&1 == 0) {
return -1;
}
return 1;
}
Upvotes: 12
Reputation: 533530
I would normalise all the numbers and then sort them.
public static void main(String[] args) {
int[] values = {Integer.MIN_VALUE, 0, Integer.MAX_VALUE - 1, Integer.MIN_VALUE + 1, -1, 1, Integer.MAX_VALUE};
for (int i = 0; i < values.length; i++) {
int value = encode(values[i]);
assert decode(value) == values[i];
values[i] = value;
}
Arrays.sort(values);
for (int i = 0; i < values.length; i++)
// give back the original value.
values[i] = decode(values[i]);
System.out.println(Arrays.toString(values));
}
private static int decode(int value) {
return value >= 0
? Integer.MAX_VALUE - (value << 1)
: Integer.MIN_VALUE + (value << 1);
}
private static int encode(int value) {
return (value & 1) == 0
? (value >> 1) + Integer.MIN_VALUE / 2
: Integer.MAX_VALUE / 2 - (value >> 1);
}
prints
[-2147483648, 0, 2147483646, 2147483647, 1, -1, -2147483647]
There is extra shifting here so very large numbers are not mangled. (which is why the number is divided by two)
Upvotes: 0
Reputation:
You could do as follows
public ArrayList<Integer> sort(Integer[] input) {
int length = input.length;
ArrayList<Integer> oddNumber = new ArrayList<Integer>(0);
ArrayList<Integer> evenNumber = new ArrayList<Integer>(0);
for (int i = 0; i < length; i++) {
Integer val = input[i];
if(isEven(val)){
evenNumber.add(val);
} else {
oddNumber.add(val);
}
}
Collections.sort(evenNumber);
Collections.sort(oddNumber, Collections.reverseOrder());
evenNumber.addAll(oddNumber);
return evenNumber;
}
public boolean isEven(Integer x) {
return x % 2 == 0;
}
EDIT
I implemented a comparator based on Jesper algorithm.
public ArrayList<Integer> sort(Integer[] input) {
ArrayList<Integer> output = new ArrayList<Integer>(0);
output.addAll(Arrays.asList(input));
Collections.sort(output, new EvenOddComparator());
return output;
}
public class EvenOddComparator implements Comparator<Integer>
{
final int BEFORE = -1;
final int EQUAL = 0;
final int AFTER = 1;
@Override
public int compare(Integer o1, Integer o2) {
if (o1 % 2 == 0 && o2 % 2 != 0) {
return BEFORE;
} else if (o1 % 2 != 0 && o2 % 2 == 0) {
return AFTER;
} else if (o1 % 2 == 0 && o2 % 2 == 0) {
return o1.compareTo(o2);
} else if (o1 % 2 != 0 && o2 % 2 != 0) {
return o2.compareTo(o1);
}
return EQUAL;
}
}
Cheers.
Upvotes: 5
Reputation: 30865
Ad1.
We need to create a Comparator<Tnteger>
that works with this rules.
Ad2. I do not understand.
Upvotes: 0
Reputation: 66166
If all numbers are positive, you can multiply your odd numbers by "-1", do a standard sort, then again multiply all odd numbers by "-1".
If you want the order as in a question, you'll also have to swap "negative" and "positive" array parts before the 2nd multiplication.
Total overhead: 3 more loops in addition to a chosen sort algorithm.
List<Integer> numbers = new ArrayList<Integer>();
//add some numbers here
//12 67 1 34 9 78 6 31 <-- in the list
for (int i = 0; i < numbers.size(); i++) {
if (numbers.get(i) % 2 == 1) {
numbers.set(i, numbers.get(i) * (-1));
}
}
//12 -67 -1 34 -9 78 6 -31 <-- before sort
sort(numbers);
//-67 -31 -9 -1 6 12 34 78 <-- after sort
swapNegativeAndPositiveParts(numbers);
//6 12 34 78 -67 -31 -9 -1 <-- after swap
for (int i = 0; i < numbers.size(); i++) {
if (numbers.get(i) % 2 == 1) {
numbers.set(i, numbers.get(i) * (-1));
}
}
//6 12 34 78 67 31 9 1 <-- after second multiplication
Upvotes: 0
Reputation: 206816
If it is not required that you implement the whole sorting algorithm yourself, you could just use Collections.sort(list, comparator)
, and you'll need to supply your own Comparator<Integer>
implementation that compares the numbers and returns a result so that the numbers are sorted in the order that is defined by the rules.
The comparator would have to implement these rules:
If you have the numbers in an array instead of a List
, then use Arrays.sort(array, comparator)
.
Upvotes: 2
Reputation: 52185
You can use one data structure which holds all the numbers and then, create two SortedSets, one for odd and one for even. The sorted set can take a Comparator
as a parameter which allows you to sort elements while you enter data.
Once that you will have gone through all the numbers, create a new collection which merges the two sorted sets.
You can also replace the sorted sets by using two Lists
. Once that you have added all the numbers, call Collections.sort()
on the lists and then merge as before.
Upvotes: 0
Reputation: 12674
I dont think any one Collection is necessarily better than the other, I would use something that extends a list rather than a set though and definitely not a map.
What I would do is that in my Collection.sort
call, I would check if the number mod 2 (number%2
) is zero then I would would do a simple compareTo
otherwise I would do an Integer.MAX_INT - oddNumber
and then do a compareTo. That way the larger the odd number the smaller the generated number and it will be sorted to the end of the list in a descending order.
Integer num1 = (o1%2 == 0)? new Integer(o1) : new Integer(Integer.MAX_INT - o1);
Integer num2 = (o2%2 == 0)? new Integer(o2) : new Integer(Integer.MAX_INT - o2);
return num1.compareTo(num2);
Above is just sudo code, don't take it too literally, its just to give you an idea.
Upvotes: 0