Created
July 23, 2016 19:11
-
-
Save igormukhin/c0be9dd8ce92228b4a0df857b533fb33 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.