1、问题描述
输入一个整型数组,把数组中的所有数拼接起来组成一个拼接数,将所有拼接数中最小的那个打印出来。例如输入数组{3,32,321}\{3,32,321\}{3,32,321},则打印出的这3个数的最小拼接数是321323。
2、解题思路
- 边界条件:(1)输入数组为空指针或空数组;
- 思路1:这道题可以采用动态规划来做。假设N[i]N[i]N[i]表示使用数组中iii个数排成的最小数。我们首先从几个例子来分析最优子结构:
- (1)例1:{3,32,321}\{3,32,321\}{3,32,321}
- 为了便于观察,我们不将数直接拼接,而是使用“-”间隔开来
- N[1]N[1]N[1](使用数组中1个数排成的最小数):{3}\{3\}{3}
- N[2]N[2]N[2](使用数组中的2个数排成的最小数):{32−3}\{32-3\}{32−3}
- N[3]N[3]N[3](使用数组中的3个数排成的最小数):{321−32−3}\{321-32-3\}{321−32−3}
- (2)例2:{1,2,3}\{1,2,3\}{1,2,3}
- N[1]N[1]N[1](使用数组中1个数排成的最小数):{1}\{1\}{1}
- N[2]N[2]N[2](使用数组中的2个数排成的最小数):{1−2}\{1-2\}{1−2}
- N[3]N[3]N[3](使用数组中的3个数排成的最小数):{1−2−3}\{1-2-3\}{1−2−3}
- 从这两个例子中可以看出,N[i]N[i]N[i]可以通过N[i−1]N[i-1]N[i−1]构造得到,在构造N[i]N[i]N[i]时,每次都从未在N[i−1]N[i-1]N[i−1]中出现的剩余数中选择一个最小的数,然后将这个最小的数拼在N[i−1]N[i-1]N[i−1]的开头或末尾。相应的状态转移方程如下:
- N[i]={numberif i=0min(N[i−1]+number,number+N[i−1]if i>0N[i]=
\begin{cases}
number & if \ i=0 \\
min(N[i-1] + number,number + N[i-1] & if\ i > 0
\end{cases}N[i]={numbermin(N[i−1]+number,number+N[i−1]if i=0if i>0
其中,numbernumbernumber表示未在N[i−1]N[i-1]N[i−1]出现的数中的最小数,N[i−1]+numberN[i-1] + numberN[i−1]+number表示将number拼接在N[i−1]N[i-1]N[i−1]的结尾,而number+N[i−1]number + N[i-1]number+N[i−1]相反。这种方法的时间复杂度为O(n2)O(n^{2})O(n2),耗时的操作是查找最小的数number和两个字符串的大小比较。
3、代码实现
import java.util.ArrayList;
public class Problem_33 {
public String PrintMinNumber(int [] numbers) {
if(numbers == null || numbers.length <=0){
return "";
}
ArrayList<Integer> numbers_back = new ArrayList<Integer>();
for(int j = 0; j<numbers.length;j++){
numbers_back.add(numbers[j]);
}
String [] minPermutation = new String[numbers.length];
for(int i = 0; i < numbers.length; i++){
Integer minx = this.findMinOfOthers(numbers_back);
String minxs = String.valueOf(minx);
if(i==0){
minPermutation[i]=minxs;
}
else {
String candidate1 = minPermutation[i-1] + minxs;
String candidate2 = minxs + minPermutation[i-1];
if(candidate1.compareTo(candidate2) < 0){
minPermutation[i] = candidate1;
}
else {
minPermutation[i] = candidate2;
}
}
numbers_back.remove(minx);
}
System.out.println("result="+minPermutation[numbers.length - 1]);
return minPermutation[numbers.length - 1];
}
private int findMinOfOthers(ArrayList<Integer> numbers){
Integer minx = numbers.get(0);
for(int k = 1; k < numbers.size(); k++){
if (numbers.get(k) < minx){
minx = numbers.get(k);
}
}
return minx;
}
}