把数组排成最小的数(Java)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u013132035/article/details/80768711

题目:

输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如,输入数组{3,  32,321},则打印出这3个数字能排成的最小数字321323。

第一思路:利用全排列,然后比较全排列中的数字,得出最小数字。

代码实现:

public class Main {
	
	public static void permutation(String[] str) {
		permutation(str, 0, str.length - 1);
	}
	
	private static List<String> list = new ArrayList<String>();
	private static StringBuilder sb = new StringBuilder();
	
	/** 数组中从索引begin到索引end之间的子数组参与到全排列 */
	public static void permutation(String[] str, int begin, int end) {
		if (begin == end) { // 只剩最后一个字符时为出口
			for (int i = 0; i < str.length; ++i) {
				sb.append(str[i]);
			}
			list.add(sb.toString());
			sb.delete(0, sb.toString().length());
		} else {
			for (int i = begin; i <= end; ++i) { // 每个字符依次固定到数组或子数组的第一个
				if (canSwap(str, begin, i)) { // 去重
					swap(str, begin, i); // 交换
					permutation(str, begin + 1, end); // 递归求子数组的全排列
					swap(str, begin, i); // 还原
				}
			}
		}
	}
    
    //交换
	public static void swap(String[] str, int from, int to) {
		String temp = str[from];
		str[from] = str[to];
		str[to] = temp;
	}

	// 判断去重
	public static boolean canSwap(String[] str, int begin, int end) {
		for (int i = begin; i < end; ++i) {
			if (str[i] == str[end]) {
				return false;
			}
		}
		return true;
	}

	public static void main(String[] args) {
		final String[] str = new String[] { "3", "32", "321" };
		permutation(str);
		String str2 = list.get(0);
		for(String str1 : list){
			if(str1.compareTo(str2) < 0){
				str2 = str1;
			}
		}
		System.out.println(str2);
	}
}

第二种思路:这道题目其实是希望我们能够找到一个排序规则,数组根据这个规则排序之后能排成一个最小的数字。要确定排序规则,就要比较两个数字,也就是给出两个数字m和n,我们需要确定一个规则判断m和n哪个应该排在前面,而不是仅仅比较这两个数字的值哪个更大。

确立规则:

根据题目的要求,两个数字m和n能拼成数字mn和nm。如果mn<nm,那么我们应该打印出mn,即m应该排在n的前面,我们此时定义m小于n;反之,如果nm<mn,我们定义n小于m。如果mn=nm,我们定义m等于n。(注:符号的<,>, =是常规意义的数值大小,而文字的“大于”,“小于”,“等于”表示我们新定义的大小关系)。

因存在大数问题,故我们把数字转化为字符串,另外把数字m和数字n拼接起来得到mn和nm,它们的位数肯定是相同的,因此比较它们的大小只需要按照字符串大小的比较规则就可以了。

代码实现:

public class Main1 {

	public static String printMinNumber(int []numbers){
		if(numbers == null || numbers.length == 0){
			return "";
		}
		int len = numbers.length;
		String []str = new String[len];
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < len; i++) {
			str[i] = String.valueOf(numbers[i]);
		}
		
		//这里根据自己定义的排序规则,新的排序规则,如若取最大值,~c1.compareTo(c2)
		Arrays.sort(str, new Comparator<String>() {
			public int compare(String str1, String str2) {
				String c1 = str1 + str2;
				String c2 = str2 + str1;
				return c1.compareTo(c2);
			}
		});
		for(int i = 0; i < len; i++){
            sb.append(str[i]);
        }
        return sb.toString();
	}
	
	public static void main(String[] args) {
		int a[] = {3, 32, 321};
		System.out.println(printMinNumber(a));
		
	}
}

小结:善于发现规律,自定义新规则,并能证明新规则的有效性。

猜你喜欢

转载自blog.csdn.net/u013132035/article/details/80768711
今日推荐