排列数组中数字得出最大数算法

今日见一有意思的算法题目:“编写一个能将给定非负整数列表中的数字排列成最大数字的函数。例如,给定[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 c = new Comparator(){

		@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= 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. 你提供给我的代码有一点点错误,我偷偷没有告诉你。。。)



你可能感兴趣的:(java,算法)