今日见一有意思的算法题目:“编写一个能将给定非负整数列表中的数字排列成最大数字的函数。例如,给定[50,2,1,9],最大数字为95021。”
最简单的是爆力破解,数组全排列,最后拼出来的数取最大的。然而没有啥技术含量,于是摒弃。
接下来分析,另外一种实现方法,
分析:为了要得到最大值,那么要从每个数的最高位比较,取最高的(比如第一个数字是9的)放在拼接数字最前面。最完9的,就看有没有8的,依次类推。这是第一步。
第二个问题是,如果有多个数字最高位都是9,怎么办呢?显然,比较它们的第二位,谁数字大谁在最前面。
这里又有一个特殊情况,比如最高位都是7的三个数(7,75,78),这时怎么处理呢?很显然,这三个数拼起来拼得最大值是78775。看见没,10以内的数字放的位置比较特殊。这是因为78,75后面的数字分别是8和5, 一个比7大,一个比7小。所以数字7就放在了78和75中间才会使拼起来的数最大。
实现代码如下:
import java.util.Arrays;
import java.util.Comparator;
/**
* Problem Description:
* 编写一个能将给定非负整数列表中的数字排列成最大数字的函数。例如,给定[50,2,1,9],最大数字为95021。
*
* This is a solution for this problem.
*
* @author Administrator
*
*/
public class FindMaxArray {
static Comparator<Integer> c = new Comparator<Integer>(){
@Override
public int compare(Integer o1, Integer o2) {
// TODO Auto-generated method stub
return myCompare(o1.toString(), o2.toString());
//return 0;
}
int myCompare(String s1, String s2) {
String shortOne, theOther;
shortOne = s1;
theOther = s2;
if(s1.length() > s2.length()) {
shortOne = s2;
theOther = s1;
}
String tmp = theOther.substring(0, shortOne.length());
if(tmp.equals(shortOne) && shortOne.length() > 1){
return s1.compareTo(s2);
}else{
return 0 - s1.compareTo(s2);
}
}
};
public void magicSort(Integer a[]){
Arrays.sort(a, c);
int lastIndex = a.length-1;
if (lastIndex < 0 ) return ;
Integer t = a[lastIndex];
if(t<10 && lastIndex>0){
int i=0;
for(;i<lastIndex;i++){
int j=1;
String tmp = a[i].toString();
int strLength = tmp.length();
while(j<strLength && tmp.charAt(j)-'0' >= t){
j++;
}
if(j != strLength) break;
}
if(i!=lastIndex){
for(int k = lastIndex; k>i; k--){
a[k] = a[k-1];
}
a[i] = t;
}
}
}
public void findMaxNum(Integer[] nums){
Integer[][] buckets = new Integer[10][];
int[] assist = new int[10];
String[] numStrs = new String[nums.length];
int i=0;
for(int n : nums) {
numStrs[i] = String.valueOf(n);
++i;
}
i=0;
for(String numstr : numStrs){
assist[numstr.charAt(0)-'0']++;
}
i=1;
for(; i<10; i++){
buckets[i] = new Integer[assist[i]];
}
i=0;
for(String numstr: numStrs){ // 将数字分桶装
int index = numstr.charAt(0)-'0';
Integer[] tmp = buckets[index];
tmp[tmp.length-assist[index]] = nums[i];
assist[index]--;
i++;
}
i=1;
for(; i<10; i++){
magicSort(buckets[i]); // sort 每个桶中的数 in a special way
}
StringBuilder sb = new StringBuilder();
for(i=9;i>0;i--){ // 从大往小输出拼接
for(Integer item : buckets[i]){
sb.append(item);
}
}
System.out.println(sb.toString());
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Integer[] nums = {3,2,4,5,98,12,971,9,45,97,90};
Integer[] nums2 = {50, 2, 1, 9};
System.out.println(Arrays.toString(nums));
FindMaxArray fma = new FindMaxArray();
fma.findMaxNum(nums2);
}
}
说得比较简单,给能看懂的兄弟看吧!!!
#############################################python实现(好简单呀)#################################################
def get_max_num(given_list):
max_len = len(str(max(given_list)))
str_data = [(('{:'+str(item)[-1]+'<'+str(max_len)+'}').format(item),
len(str(item))) for item in given_list]
print('tuple data= ', str_data)
sorted_str = sorted(str_data, reverse=True)
print('sort_data= ', sorted_str)
decode_str = [sd[0][:sd[1]] for sd in sorted_str]
print('result= ', ''.join(decode_str))
get_max_num([9,99,77,123,8,78,76,7])在此谢谢熟悉Python的凯恒(p.s. 你提供给我的代码有一点点错误,我偷偷没有告诉你。。。)

博客探讨了一道算法问题,即如何将非负整数数组排列成最大的数字。通过分析,提出从高位开始比较,优先选择较大的数字,并处理高位相同的情况。文中给出了Python的简洁实现代码。

被折叠的 条评论
为什么被折叠?



