题目:
Given a list of non negative integers, arrange them such that they form the largest number.
For example, given [3, 30, 34, 5, 9]
, the largest formed number is 9534330
.
Note: The result may be very large, so you need to return a string instead of an integer.
思路:
对于一组数字组成一个数字,越大的数在前面,组成的数字就越大。这个规则显而易见。
但是这条规则多用于位数相同的该组数字相互比较。对于上面这组,3,30,34这三个数字,怎么样才最大呢?
首先,第一位均为3,而3只有一位,如何跟剩下两个比较?这是个难点,也是本题的关键所在。
其实如果按照这条思路想下去,就很难想通了。(虽然我相信一定能够证明这种方法能够得到结果,但你如果做了,
就会得到我最后附上的方法的后果:TLE(TimeLimitExceed):借助比较甚至是递归全排列方法寻找最大的一种组合,简直是慢,所以,当你想到使用递归得到这个题的答案的时候就不要往下想了。)
显然,30和34应该把34放在前面,因为3034<3430;同样,3和30哪个应该在前?不如组合一下,也就是
330和303。因此3放在30前面。而3和34比较之后得到334和343,显然34放在前面。由此得到两者的前后顺序。(这也就是我为什么会想到使用递归方法得到所有全排列最终寻找一个最大的原因。)
因此,本题的关键就是根据以上的推导建立比较规则,借助Comparator(或者Comparable,如果你的类可以实现该接口)
得到顺序。使用到Arrays.sort(str[],new Comparator{});
本题提醒我们数字可能会很大,因此组合和比较的时候都是用字符串。还好字符串的比较可以使用comparatorTo方法。
AC代码:
public class Largest_Number { public String largestNumber(int[] num) { if(num==null || num.length==0) return ""; String[] nums = new String[num.length]; for(int i=0;i<num.length;i++){ nums[i] = ""+num[i]; } Arrays.sort(nums,new Comparator<String>() { @Override public int compare(String o1, String o2) { return (o2+o1).compareTo(o1+o2); } }); String RST=""; for(int i=0;i<nums.length;i++){ RST+=nums[i]; } if(RST.charAt(0)=='0') RST="0"; return RST; } public static void main(String[] args){ Largest_Number largest_number = new Largest_Number(); int[] num = {3, 30, 34, 5, 9}; String rst = largest_number.largestNumber(num); System.out.println(rst); } }
超时情况中用到了全排方法(得到全排列方法):
<pre name="code" class="java">public void getTotalSort(int[] nums,int start){ if(start==nums.length){ List<Integer> lst = new LinkedList<Integer>(); for(int i=0;i<nums.length;i++){ lst.add(nums[i]); } numLst.add(lst); } else{ for(int i=start;i<nums[i];i++){ if(i>start && nums[i]==nums[start]) continue; int tmp = nums[i]; nums[i] = nums[start]; nums[start] = tmp; getTotalSort(nums,start+1); nums[start] = nums[i]; nums[i] = tmp; } } }