Solution 1
比较直观的想法就是从最高位进行排序,但是题目里的第二个例子给出了一个这种直觉的反例:3和30,按照该逻辑排序应该是303,但是最优的方案应该是330。
为了覆盖这种情形,这里参考最大数 - 最大数 - 力扣(LeetCode)的官方题解方案的方法,对连续的拼接方案进行比较。题解中给出了排序关系的充分性与传递性的证明了其全序关系,因此可以保证其效果
- 时间复杂度: O ( n ⋅ log n ) O(n \cdot \log n ) O(n⋅logn),其中 n n n为输入数组中元素的个数,虽然有字符串转换的过程,但是由于给定输入的范围固定,因此转换过程实际上渐进为常数复杂度,因此只需要考虑排序本身的时间消耗
- 空间复杂度: O ( n log n ) O(n \log n) O(nlogn),其中 n n n为输入数组中元素的个数,这里同理,比较占用空间为常数复杂度,因此只考虑排序的空间占用
class Solution {
public:
string largestNumber(vector<int>& nums) {
sort(nums.begin(), nums.end(), this->cmp);
string ans = "";
// 特殊情况:全是0
if (nums[0] == 0) {
ans += "0";
} else {
for (int item: nums) {
ans += to_string(item);
}
}
return ans;
}
private:
bool static cmp(int &a, int &b) {
// 拼接方案检查排序
// long basea = 10, baseb = 10;
// while (basea <= a) { basea *= 10; }
// while (baseb <= b) { baseb *= 10; }
// long cata = baseb * a + b;
// long catb = basea * b + a;
string sa = to_string(a), sb = to_string(b);
auto cata = sa + sb;
auto catb = sb + sa;
return cata > catb;
}
};
Solution 2
Solution 1的Python实现
class Solution:
def largestNumber(self, nums: List[int]) -> str:
class Cmp(int):
def __lt__(self, other: int) -> bool:
cata = str(self) + str(other)
catb = str(other) + str(self)
return cata > catb
nums = sorted(nums, key=Cmp)
if nums[0] == 0:
ans = "0"
else:
ans = "".join(map(str, nums))
return ans