题目描述
输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。
解题思路:首先想到的是把数字转化成字符串,然后全排列。在比较大小。(要想到全排列的思想是基于交换实现的,每一位和后面的交换)
解题代码:
1.基于全排列的方法(回头补上,顺便复习一下字符串全排列算法)
2.自定义一个排序规则
对vector容器内的数据进行排序,按照 将a和b转为string后 若 a+b<b+a a排在在前 的规则排序,
如 2 21 因为 212 < 221 所以 排序后为 21 2 to_string() 可以将int 转化为string
class Solution {
public:
static bool cmp(int a,int b)
{
string A="",B="";
A+=to_string(a);
A+=to_string(b);
B+=to_string(b);
B+=to_string(a);
return A<B;
}
string PrintMinNumber(vector<int> numbers) {
string res="";
if(numbers.size()<=0)
return res;
sort(numbers.begin(),numbers.end(),cmp); //自定义比较操作
for(int i=0; i<numbers.size(); i++)
res+=to_string(numbers[i]);
return res;
}
};
PS:sort中的比较函数compare要声明为静态成员函数或全局函数,不能作为普通成员函数,否则会报错。 因为:非静态成员函数是依赖于具体对象的,而std::sort这类函数是全局的,因此无法再sort中调用非静态成员函数。静态成员函数或者全局函数是不依赖于具体对象的, 可以独立访问,无须创建任何对象实例就可以访问。同时静态成员函数不可以调用类的非静态成员。
class Solution {
public:
static bool cmp(const string& str1,const string& str2)
{
string s1=str1+str2;
string s2=str2+str1;
return s1<s2; //这里字符串有比较操作符(<),可以比较大小
}
string PrintMinNumber(vector<int> numbers) {
string res="";
if(numbers.size()<=0)
return res;
vector<string> str;
for(int i=0; i<numbers.size(); i++)
str.push_back(to_string(numbers[i]));
sort(str.begin(),str.end(),cmp); //自定义比较操作
for(int i=0; i<numbers.size(); i++)
res+=str[i];
return res;
}
};
注意下面代码中 stringstream的用法
class Solution {
public:
static bool compare( const string &st1,const string &st2){
string s1 = st1+st2;
string s2 = st2+st1;
return s1<s2;
}
string PrintMinNumber(vector<int> numbers) {
string result;
if(numbers.size()<=0){
return result;
}
vector<string> strNum;
for(int i=0;i<numbers.size();i++ ){
stringstream ss;
ss<<numbers[i];
string s = ss.str();
strNum.push_back(s);
}
sort(strNum.begin(),strNum.end(),compare);
for(int i=0;i<strNum.size();i++){
result.append(strNum[i]);
}
return result;
}
};