版权声明:本文为博主原创文章,未经博主允许不得转载。 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));
}
}
小结:善于发现规律,自定义新规则,并能证明新规则的有效性。