繁体   English   中英

按升序对所有偶数进行排序,然后按集合中的降序对所有奇数进行排序

[英]Sort all even numbers in ascending order and then sort all odd numbers in descending order in a collection

这是一个面试问题。

给出了一些随机数(假设在整数数组中)。

  1. 我们如何先按升序对所有偶数进行排序,然后按降序对所有奇数进行排序。
  2. 哪个系列最适合。

输入数字:

12 67 1 34 9 78 6 31

保存在Collection中的输出:

6 12 34 78 67 31 9 1 

任何支持使用自定义比较器进行排序的集合都可以 - 甚至是数组。 按如下方式实现自定义比较器:

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;
    }

编辑

我实现了一个基于Jesper算法的比较器。

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;
        }

    }

干杯。

这是代码:

@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;
        }
    }
}
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);
    }
}

如果您不需要自己实现整个排序算法,您可以使用Collections.sort(list, comparator) ,并且您需要提供自己的Comparator<Integer>实现,该实现比较数字并返回结果,数字按规则定义的顺序排序。

比较国必须实施这些规则:

  1. 如果第一个数是偶数而第二个数是奇数,则返回-1(因为偶数必须在奇数之前)。
  2. 如果第一个数字是奇数而第二个数字是偶数,则返回1(因为偶数必须在奇数之前)。
  3. 如果两个数字都是偶数:比较两个数字,如果第一个<秒则返回-1,如果相等则返回0,如果第一个>秒则返回1(对偶数数字进行排序)。
  4. 如果两个数字都是奇数:比较两个数字,如果第一个<秒则返回1,如果相等则返回0,如果第一个>秒则返回-1(对奇数减号进行排序)。

如果您有数组而不是List ,那么使用Arrays.sort(array, comparator)

我不认为任何一个集合必然比另一个更好,我会使用扩展列表而不是集合的东西,但绝对不是地图。

我要做的是在我的Collection.sort调用中,我会检查数字mod 2( number%2 )是否为零然后我会做一个简单的compareTo否则我会做一个Integer.MAX_INT - oddNumber然后做一个相比于。 这样,奇数越大,生成的数字越小,它将按降序排序到列表的末尾。

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代码,不要过于字面意思,只是为了给你一个想法。

如果所有数字都是正数,则可以将奇数乘以“-1”,进行标准排序,然后再将所有奇数乘以“-1”。

如果您希望订单在问题中,您还必须在第二次乘法之前交换“负”和“正”数组部分。

总开销:除了选择的排序算法之外还有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

您可以使用一个包含所有数字的数据结构,然后创建两个SortedSet ,一个用于奇数,一个用于偶数。 排序集可以将Comparator作为参数,允许您在输入数据时对元素进行排序。

一旦你完成所有数字,就创建一个新的集合,合并两个有序的集合。

您还可以使用两个Lists替换已排序的集。 一旦你添加了所有数字,在列表上调用Collections.sort()然后像以前一样合并。

AD1。 我们需要创建一个符合此规则的Comparator<Tnteger>

  1. 如果我们将偶数与奇数进行比较,那么偶数也会更大。
  2. 如果我们比较两个奇数,结果就像我们想要的那样排序。
  3. 如果我们比较两个偶数,结果就像我们想要的那样排序。

AD2。 我不明白。

像这样:

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 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]

这里有额外的转移,所以非常大的数字不会被破坏。 (这就是数字除以2的原因)

我刚刚编写了一个快速示例,如下所示:

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 2 3 4 5 6 7 8 9 10结果是:[9,7,5,3,1,2,4,6,8,10]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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