最近在刷leetcode,看到一个问题很有意思。
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,5,9],你要将这些数组顺序重新排列使得重新排列后如果合并为一个数字,这个数字最大。很显然9应该放在最高位,接下来是5,那3,30,34这三个数应该遵循怎么样的规律排序呢?读者不妨思考一下。
我们首先考虑3和30,330>303,因而如果排序的话,3应该“大于”30,而3和34呢,343>334,所以34应该大于3,我们可以认为,3=33=3333...,这样就说的通了,30<33<34,而每个个位数都可以无限扩展自己。
现在我们只需要按照这个原则来对这个数组排序即可。排好序后将元素从后向前组合起来就是结果。
然而在最后代码实现的时候,我发现这个策略并不完美,试想如何分辨308和3088的大小?需要写一堆逻辑处理这个大小关系。
后来我突然想到,在具体实现中,只需要考虑两个元素的大小关系,完全可以穷举,直接比较3083088和3088308的大小关系,逻辑简单清晰而且没有漏洞!以下是代码实现:
public String largestNumber(int[] nums) { int lenn = nums.length; String []strs = new String[lenn]; for(int i=0;i(){ @Override public int compare(String a, String b) { int lens =a.length()+b.length(); String s1 = a+b,s2 =b+a; for(int i=0;i s2.charAt(i)) return 1; if(s1.charAt(i) < s2.charAt(i)) return -1; } return 1; } }); String res=""; for(int i=0;i 0)res += strs[lenn-1-i]; return res.length()>0?res:"0"; }
现在发散开去,只要某个算法问题可以转化成对数组排序,我们就可以自己实现一套排序策略,这样一类问题就可以很好的解决了。而且在这个排序函数中,你只要考虑两个元素的大小关系,使用穷举法会得到意想不到的效果。
很多语言都提供了对自定义策略排序的支持,例如java:
Arrays.sort(int []a,new Comparator(){ @Override public int compare(int a,int b){ if() return 1; // 实现你的策略 返回1表示a>b,-1表示a