PROBLEM

剑指 Offer 45. 把数组排成最小的数

难度 中等

MY ANSWER

无。

BETTER SOLUTION

本质上是排序问题,排序规则为(字符串比较):

  • 拼接字符串x + y > y + x,则x > y
  • 反之x + y < y + x,则x < y

将数组按规则从小到大排序再连接即为答案。时间复杂度O(nlogn),空间复杂度O(n)。

两种实现方法:

手写快排

class Solution {
public:
string minNumber(vector<int>& nums) {
vector<string> strs;
for(int i = 0; i < nums.size(); i++)
strs.push_back(to_string(nums[i]));
quickSort(strs, 0, strs.size() - 1);
string res;
for(string s : strs)
res.append(s);
return res;
}
private:
void quickSort(vector<string>& strs, int l, int r) {
if(l >= r) return;
int i = l, j = r;
while(i < j) {
while(strs[j] + strs[l] >= strs[l] + strs[j] && i < j) j--;
while(strs[i] + strs[l] <= strs[l] + strs[i] && i < j) i++;
swap(strs[i], strs[j]);
}
swap(strs[i], strs[l]);
quickSort(strs, l, i - 1);
quickSort(strs, i + 1, r);
}
};

sort更改比较函数

class Solution {
public:
string minNumber(vector<int>& nums) {
vector<string> strs;
string res;
for(int i = 0; i < nums.size(); i++)
strs.push_back(to_string(nums[i]));
sort(strs.begin(), strs.end(), [](string& x, string& y){ return x + y < y + x; });
for(int i = 0; i < strs.size(); i++)
res.append(strs[i]);
return res;
}
};

SUMMARY

  • 善用string的字典序比较,c++可直接使用符号;
  • 复习快排;
  • sort第三个参数可改写比较函数;
  • 匿名函数:[](参数){函数体}