把数组排成最小的数
题目:输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。
输入:{3,32,321}
输出:321323
思路:1、主要的思路是利用递归去判断两个数字m和n,合并后是mn大还是nm大。
2、在这里需要注意如果2个由int类型表示的数字,在合并后很可能会超出int类型能表示的范围,所以这里还是一个隐形的大数问题。
3、对于大数问题最好的解决办法是利用字符串来解决,并且mn和nm这2个数字的位数都是一样的,更可以用字符串来解决。
总结:于是问题就变成递归的每次比较2个数字是合并前大还是合并后大,然后再输出最终合并的数字,该数字就是最小的数字
Ps:这里还是需要注意一个事情,我们在对数组进行排列前,要先对数组进行一次排序,让小的数字排在前面,这样对后面判断mn和nm比较有优势,举个例子来说:1 3 5 4 2,那么如果不排序的话,只能输出13542,而排序后的数组是:1 2 3 4 5,对应输出结果是12345,12345<13542,这就是在合并前排序的重要性
/*
题目:把数组排成最小的数
*/
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
string minMerge(string str1,string str2){
//这里有可能str1和str2都是int或者long long类型范围内表示不了的数,所以只能一个字符一个字符的比较
for (int i = 0; i < str1.size(); i++){
if ((str1[i] - '0') < (str2[i] - '0')){
return str1;
}
else if ((str1[i] - '0') > (str2[i] - '0')){
return str2;
}
}
return str1;
}
string PrintMinNumber(vector<int> numbers) {
string str1;
string str2;
sort(numbers.begin(), numbers.end());
if (numbers.size() == 0){
return str1;
}
str1 = to_string(numbers[0]);
for (int i = 1; i < numbers.size(); i++){
str2 = to_string(numbers[i]);
//用str1保存合并后最小的数
str1 = minMerge(str1 + str2, str2 + str1);
}
return str1;
}
int main(){
int n;
cin >> n;
vector<int> numbers;
int temp;
for (int i = 0; i < n; i++){
cin >> temp;
numbers.push_back(temp);
}
cout << PrintMinNumber(numbers);
system("pause");
return 0;
}