题目描述
输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。
解题思路
方法一:自定义排序
1、思路:首先将int类型数组转化为string类型数组,然后对数组进行排序,排序方式定义为:若字符串a与b的拼接结果小于b与a的拼接结果,则字符串a排在前面,对应到题目就是:321与32拼接得到32132,32与321拼接得到32321,32132 < 32321,因此321排在前面。需要注意的是类成员函数有隐藏的this指针,需要将自定义的排序规则声明为static函数。
2、代码:
class Solution {
public:
static bool cmp(string a, string b) {
return (a + b) < (b + a);
}
string PrintMinNumber(vector<int> numbers) {
string ret;
vector<string> result;
for (int val : numbers) {
result.push_back(to_string(val));
}
sort(result.begin(), result.end(), cmp);
for (string val : result) {
ret += val;
}
return ret;
}
};
3、复杂度:
时间复杂度:O();
空间复杂度:O(n)。
方法二:全排列
1、思路:遍历数组的全排列,比较每个排列的大小,最后返回最小值。
2、代码:
class Solution {
public:
void perm(int pos, vector<int> nums, string &ret) {
if (pos + 1 == nums.size()) {
string tmp = "";
for (int val : nums)
tmp += to_string(val);
ret = min(ret, tmp);
}
for (int i = pos; i < nums.size(); i++) {
swap(nums[pos], nums[i]);
perm(pos + 1, nums, ret);
swap(nums[i], nums[pos]);
}
}
string PrintMinNumber(vector<int> numbers) {
string ret(numbers.size(),'9');
perm(0, numbers, ret);
return ret;
}
};
3、复杂度:
时间复杂度:O(nn!),数组的全排列共有n!种,遍历每个排列得到字符串需要O(n);
空间复杂度:O(n)。
方法三:库函数
1、思路:调用全排列的库函数std::next_permutation(first, last),比较每次排列的大小,返回最小值。
2、代码:
class Solution {
public:
string PrintMinNumber(vector<int> numbers) {
string ret(numbers.size(),'9');
vector<string> result;
for (int val : numbers)
result.push_back(to_string(val));
sort(result.begin(), result.end());
do {
string tmp = "";
for (string val: result) tmp += val;
ret = min(tmp, ret);
} while (next_permutation(result.begin(), result.end()));
return ret;
}
};
3、复杂度:
时间复杂度:O(nn!);
空间复杂度:O(n)。