输入一个非负整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。
/*
本质上是一个排序问题。设数组nums中任意两数字的字符串为 x 和 y,则规定排序判断规则为:
若拼接字符串 x + y > y + x,则 x“大于”y ;
反之,若 x + y < y + x,则 x “小于”y ;
其中,x “小于” y代表:排序完成后,数组中 x应在 y左边;“大于” 则反之。
算法流程:
1.初始化: 字符串列表 strs,保存各数字的字符串格式;
2.列表排序: 应用以上 “排序判断规则” ,对 strs执行排序;
3.返回值: 拼接 strs 中的所有字符串,并返回。
*/
方法1:c++自带排序函数,时间复杂度 O(N log N),空间复杂度 O(N)
string PrintMinNumber(vector<int> numbers)
{
vector<string> strs;
string s;
for(auto n:numbers)
{
strs.push_back(to_string(n));
}
sort(strs.begin(),strs.end(),[](string& s1,string& s2){return s1+s2<s2+s1;});//引用传递,所以要用begin和end指向向量容器的地址
for(auto i:strs)
{
s.append(i);
}
return s;
}
方法2:手写快排,时间复杂度 O(N log N),空间复杂度 O(N)
class Solution {
public:
void quick_sort(vector<string>& s,int low,int high)
{
if(low>=high)
return;
int l=low,h=high;
string x=s[low];///注意这里有递归,所以初始值不是s[0],而是s[low]
while(l<h)
{
while((x+s[h])<=(s[h]+x)&&l<h)//这里要加等于号
h--;
s[l]=s[h];
while((x+s[l])>=(s[l]+x)&&l<h)//这里要加等于号
l++;
s[h]=s[l];
}
s[l]=x;
quick_sort(s,low,l-1);
quick_sort(s,l+1,high);
}
string PrintMinNumber(vector<int> numbers) {
vector<string> strs;
string s;
for(auto n:numbers)
{
strs.push_back(to_string(n));
}
quick_sort(strs,0,strs.size()-1);
for(auto i:strs)
{
s.append(i);
}
return s;
}
};