把数组排成最小的数(c++实现)(排序)
题目
输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。
样例输入
3 3 32 321
样例输出
321323
解析
在输出最小的数,不输出前导的0情况下,对所有数进行合理排列是首要的一点,再全部输出,其中转化为字符串处理更加方便,在构思排序的过程中应该想到字典序排列。
( 思路一)(字典序排列 )
bool cmp(const string &a, const string &b) {
return a < b;
}
可是字典序排列后就是所需的正确答案吗? 显然不是,来找个反例吧 ,比如31与3,按照字典序降序排出的是313,而313显然是最小值。那么我们要考虑排出后的值的大小,大家不难想到比如用全排列实现排列后每个数比较大小最后输出最小值不就行咯,可是全排列的复杂度不低哦为O(n!),我们再想一想如何降低它的复杂度,来很舒适的实现呢,有这样一个idea,就是你看全排列时比较每个数值长度都是一样的吧,给定2个数正反序排好数值长度也一样诶,那么对a+b和b+a进行字典序排列就很好,此时还可体现C++的漂亮,不用专门繁冗一点的函数,来看一下:
(思路二)
bool cmp(const string &a, const string &b) {
string s1 = a + b;
string s2 = b + a;
return s1 < s2;
}
完成了排序后,我们总观全局的解题步骤(输入整数n代表数组大小,依次输入整个数,进行上面思路二排序后依次输出)
代码流程
#include <bits/stdc++.h>
#include<iostream>
using namespace std;
bool cmp(const string &a, const string &b) {
string s1 = a + b;
string s2 = b + a;
return s1 < s2;
}
int main() {
int n;
cin >> n;
string a[n];
for (int i = 0; i < n; ++i) {
cin >> a[i];
}
sort(a, a + n, cmp);
for (int i = 0; i < n; ++i) {
cout << a[i];
}
return 0;
}
总结
1.理顺题目要求,拓解题思路
2.要及时考虑好运行的效率问题,探究优化