Сортировать все четные числа в порядке возрастания, а затем сортировать все нечетные числа в порядке убывания в коллекции
Это вопрос интервью.
есть некоторые случайные числа, заданные (скажем, в целочисленном массиве).
- как мы можем сначала отсортировать все четные числа в порядке возрастания, а затем отсортировать все нечетные числа в порядке убывания.
- какая коллекция подходит лучше всего.
ввод чисел:
12 67 1 34 9 78 6 31
вывод сохранен в коллекции:
6 12 34 78 67 31 9 1
13 ответов
любая коллекция, поддерживающая сортировку с помощью пользовательского компаратора, будет делать-даже массив. Реализуйте свой пользовательский компаратор следующим образом:
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;
}
вы можете сделать следующее
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;
}
редактировать
я реализовал компаратор на основе алгоритма Йеспер.
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;
}
}
Ура.
если не требуется, чтобы вы реализовали весь алгоритм сортировки самостоятельно, вы можете просто использовать Collections.sort(list, comparator)
, и вам нужно будет предоставить свой собственный Comparator<Integer>
реализация, которая сравнивает числа и возвращает результат, чтобы числа были отсортированы в порядке, определенном правилами.
компаратор должен был бы реализовать эти правила:
- если первое число четное, а второе нечетное, верните -1 (потому что четные числа должны быть перед нечетными числа.)
- если первое число нечетное, а второе четное, верните 1 (потому что четные числа должны предшествовать нечетным).
- если оба числа четные: сравните оба числа, верните -1, если первый второй (сортирует четные числа по возрастанию).
- если оба числа Нечетные: сравните оба числа, верните 1, Если first second (сортирует нечетные числа по убыванию).
если у вас есть числа в массиве вместо List
, а затем использовать Arrays.sort(array, comparator)
.
вот код :
@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;
}
}
}
пакета com.Ява.утиль.коллекция;
импорт java.утиль.Матрицы; импорт java.утиль.Сборники;
публичный класс 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);
}
}
Я не думаю, что какая-либо одна коллекция обязательно лучше, чем другая, я бы использовал то, что расширяет список, а не набор, хотя и определенно не карту.
что бы я сделал, так это в моем Collection.sort
вызов, я бы проверил, если номер mod 2 (number%2
) равен нулю, тогда я бы сделал простой compareTo
в противном случае я сделал бы Integer.MAX_INT - oddNumber
а затем сделать compareTo. Таким образом, чем больше нечетное число, тем меньше сгенерированное число, и оно будет отсортировано до конца список в порядке убывания.
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);
выше-это просто код sudo, не принимайте это слишком буквально, просто чтобы дать вам идею.
вы можете использовать одну структуру данных, которая содержит все числа, а затем создайте два объект sortedsets, один для нечетных и один для четных. Сортированный набор может принимать Comparator
в качестве параметра, который позволяет сортировать элементы при вводе данных.
как только вы пройдете через все числа, создайте новую коллекцию, которая объединяет два отсортированных набора.
вы также можете заменить сортированные наборы с помощью двух Lists
. После того, как вы добавили все номера, звоните Collections.sort()
в списках, а затем объединить, как и раньше.
Если все числа положительные, вы можете умножить свои нечетные числа на "-1", сделать стандартную сортировку, а затем снова умножить все нечетные числа на"-1".
Если вы хотите порядок, как в вопросе, вам также придется поменять местами "отрицательные" и "положительные" части массива перед 2-м умножением.
общие накладные расходы: еще 3 цикла в дополнение к выбранному алгоритму сортировки.
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
Ad1.
Нам нужно создать Comparator<Tnteger>
это работает с этими правилами.
- если мы сравниваем четное число с нечетным, то четное всегда больше.
- если мы сравним два нечетных числа, результат будет таким, как мы хотели бы сортировать desc.
- если мы сравним два четных числа, результат будет таким, как мы хотели бы сортировать asc.
Ad2. Я не понимаю.
Я бы нормализовал все числа, а затем отсортировал их.
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);
}
печать
[-2147483648, 0, 2147483646, 2147483647, 1, -1, -2147483647]
здесь есть дополнительное смещение, поэтому очень большие числа не искажаются. (именно поэтому число делится на двоих)
такой:
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));
Я просто написала пример, как показано ниже:
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));
}
});
}
}
выход:
[6, 12, 34, 78, 67, 31, 9, 1]
в Java :- Лучший Подход, Минимальная Сложность
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);
}
}
выход :-
Введите Размер Массива : 10
1 Два Три Четыре Пять Шесть Семь Восемь Девять Десять Результат : [9, 7, 5, 3, 1, 2, 4, 6, 8, 10]