简体   繁体   中英

How to sort elements in an int array to create the largest number possible

I have an exercise to sort an array (type int) so I can get the largest number possible.

An example:

1,3,9 ==> 931

1,3,9,60 ==> 96031

So here is my idea: It is impossible to just sort the array to form the number that I wanted. So I can check the first number of each element in array, using the very same idea as bubble sort, just one small difference is that i use the first element to check instead of just arr[i]. But I still want to know beside using my idea, are there any other way (more efficiency). Even if your idea are the very same with my idea but you have something upgrade. Thank you very much

Solution

For the descending order we multiply here by -1 each value in the array then sort the array and then multiply back with -1. Ultimately we build the result string with string concatenation and print it out

import java.util.Arrays;

public class MyClass {
    public static void main(String args[]) {
    int[] array = {3,1,9};
    
    for (int l = 0; l < array.length; l++){
        array[l] = array[l]*-1;
    }
    Arrays.sort(array);
    for (int l = 0; l < array.length; l++){
        array[l] = array[l]*-1;
    }
    String res = "";
    
    for(int i = 0; i < array.length; i++){
        res+=array[i];
        
    }
    System.out.println(res);
    }
}

Output

931

Alternatively

Or as @Matt has mentioned in the comments you can basically concat the string in reverse order. Then there is no need anymore for the ascending to descending transformation with *-1

 import java.util.Arrays;

 public class MyClass {
     public static void main(String args[]) {
         int[] array = {
             9,
             1,
             3
         };
         String res = "";

         Arrays.sort(array);
         for (int l = array.length - 1; l >= 0; l--) {
             res += array[l];
         }



         System.out.println(res);
     }
 }

It is impossible to just sort the array to form the number that I wanted.

Actually, it isn't impossible.

What you need is to design and implement an ordering that will result in the (decimal) numbers that will make the final number to be largest to sort first; eg for the numbers in your question, the ordering is:

9 < 60 < 3 < 1

You just need to work out exactly what the required ordering is for all possible non-negative integers . Once you have worked it out, code a Comparator class that implements the ordering.

Hint: You would be able to specify the ordering using recursion...

compare first number of each int then if it is the biggest put it at beginning then you continue, if first char is equal step into the second etc etc the bigest win, if it same at max-char-size. the first selected would be pushed then the second one immediatly after as you already know.

In that maneer 9 > 60 cuz 960>609 the first char will always be the biggest in that case when u concat.

it's > 9 < not > 09 <

Hope it will work as per your requirement->

 public static void main(String[] args) {
            Integer[] arr = {1,3,3,9,60 };
            List<Integer> flat = Arrays.stream(arr).sorted((a, b) -> findfirst(b) - findfirst(a)).collect(Collectors.toList());
            System.out.println(flat);
    
        }
    
        private static int findfirst(Integer a) {
            int val = a;
            if(val>=10) {
    
                while (val >= 10) {
                    val = val / 10;
                }
            }
            return val;
        }

A lot of problems become easier when using Java streams. In this case you could convert all numbers to String and then sort in an order which picks the higher String value of two pairings, then finally join each number to one long one.

This works for your test data, but does NOT work for other data-sets:

List<Integer> list1 = List.of(1,3,9,60);
Comparator<String> compare1 = Comparator.reverseOrder();
String num1 = list1.stream().map(String::valueOf).sorted(compare1).collect(Collectors.joining(""));

The comparator Comparator.reverseOrder() does not work for numbers of different length which start with same values, so a more complex compare function is needed which concatenates values to decide ordering, something like this which implies that "459" > "45" > "451"

List<Integer> list2 = List.of(1,45,451,449,450,9, 4, 459);
Comparator<String> compare = (a,b) -> (b+a).substring(0, Math.max(a.length(), b.length())).compareTo((a+b).substring(0, Math.max(a.length(), b.length())));
String num2 = list2.stream().map(String::valueOf).sorted(compare).collect(Collectors.joining(""));

... perhaps.

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