Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save igormukhin/c0be9dd8ce92228b4a0df857b533fb33 to your computer and use it in GitHub Desktop.
Save igormukhin/c0be9dd8ce92228b4a0df857b533fb33 to your computer and use it in GitHub Desktop.
import java.math.*;
import java.util.concurrent.atomic.*;
public class Solution {
public String largestNumber(int[] nums) {
if (nums == null || nums.length == 0) {
return "0";
}
List<Integer> sortedNums = new ArrayList<Integer>(nums.length);
for (int i = 0; i < nums.length; i++) sortedNums.add(nums[i]);
Collections.sort(sortedNums);
Collections.reverse(sortedNums);
Function<List<Integer>, List<Integer>> idx2nums = indexes -> indexes.stream()
.map(i -> sortedNums.get(i))
.collect(Collectors.toList());
Function<List<Integer>, BigInteger> nums2bi = indexes -> new BigInteger(indexes.stream()
.map(n -> Integer.toString(n))
.collect(Collectors.joining()));
final AtomicReference<BigInteger> refMax = new AtomicReference<>();
final AtomicReference<List<Integer>> refMaxNums = new AtomicReference<List<Integer>>();
permutateIndexes(nums.length, indexes -> {
List<Integer> thisNums = idx2nums.apply(indexes);
BigInteger thisNum = nums2bi.apply(thisNums);
if (refMax.get() == null || thisNum.compareTo(refMax.get()) > 0) {
refMax.set(thisNum);
refMaxNums.set(thisNums);
}
}, indexes -> {
if (refMaxNums.get() == null) {
return true;
}
List<Integer> thisNums = idx2nums.apply(indexes);
List<Integer> maxNums = refMaxNums.get().subList(0, thisNums.size());
if (thisNums.equals(maxNums)) {
return false;
}
String thisNum = nums2bi.apply(thisNums).toString();
String maxNum = nums2bi.apply(maxNums).toString();
if (thisNum.length() == maxNum.length()) {
return thisNum.compareTo(maxNum) > 0;
}
int minLen = Math.min(thisNum.length(), maxNum.length());
return thisNum.substring(0, minLen).compareTo(maxNum.substring(0, minLen)) >= 0;
});
return refMax.get().toString();
}
public static void permutateIndexes(int length, Consumer<List<Integer>> consumer,
Predicate<List<Integer>> continueCheck) {
permutateIndexes(length, consumer, continueCheck, new LinkedList<Integer>());
}
private static void permutateIndexes(int length, Consumer<List<Integer>> consumer,
Predicate<List<Integer>> continueCheck,
LinkedList<Integer> indexes) {
if (indexes == null) {
indexes = new LinkedList<Integer>();
} else if (!indexes.isEmpty() && indexes.size() < length) {
if (continueCheck != null && !continueCheck.test(indexes)) {
return;
}
} else if (indexes.size() == length) {
consumer.accept(indexes);
return;
}
for (int i = 0; i < length; i++) {
if (indexes.contains(i)) {
continue;
}
indexes.add(i);
permutateIndexes(length, consumer, continueCheck, indexes);
indexes.removeLast();
}
}
}
@igormukhin
Copy link
Author

This is not a correct solution for the problem. The correct solution is to sort the input array with a special comparator. But I want to keep a nice implementation of permutateIndexes(...) for me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment