原题目描述
Given a list of non negative integers, arrange them such that they
form the largest number.Example 1:
Input: [10,2]
Output: “210”Example 2:
Input: [3,30,34,5,9]Note: The result may be very large, so you need to return a string instead of an integer.
题目大意
该题题目大意是给定一串数字,将该数字按照一定的顺序组合成一个数字,要求返回的数字是这串数字所能组成数值最大的数字(同时因为可能输出的数字会比较大,超过long所能表示的范围,所以需要返回字符串)。
解题思路
该题给定的是一个int的vector,而返回的是一个string,所以我们很自然地想要先把这些int都转成string类,然后按照一定的顺序排序,排完序之后按顺序便可以组成最大的数字。
那么,应该如何排序呢?最开始想到的办法是把转成string之后的数字按照字典序排列,例如【1, 2, 3】,按照字典序排列得出的便是321,是不是很简单,但是这只成立于vector里数字位数都相等的情况,当位数不同时,如【3,30】,按照字典序排序得到的是303,而正确结果是330,所以还需要分情况讨论(字符串长度相等和不等两种情况)。
但其实有更简单的一种排序方式,无需分情况讨论,那便是比较两个字符串的排序判断条件为 a + b > b + a,如上面所说的,因为330 > 303是成立的,那么3应该排在30的前面,以此对每两个字符串进行排序(可以使用冒泡或选择排序),便可以得到正确序列的结果,最后进行组合便得到所求字符串。
(PS,其中还有特殊情况需要另外讨论,如给定的数字都是0,那么返回的字符串应为0, 而非00,这里判断一下排完序之后的vector的第一位是不是“0”就行了)
算法复杂度分析
- 一趟遍历将Int都转为string,复杂度为O(n)
- 两层循环(冒泡)将vector进行排序,复杂度为O(n2n2)
- 一趟遍历将string依次组合,复杂度为O(n)
所以,最终算法复杂度为O(n2n2)
(PS,采用好一点的排序算法可以将排序复杂度降低)
C++实现代码
class Solution {
public:
string largestNumber(vector<int>& num) {
// 转化为string
vector<string> arr;
for(auto i:num) {
arr.push_back(to_string(i));
}
// 排序
sort(begin(arr), end(arr), [](string &s1, string &s2){
return s1 + s2 > s2 + s1;
});
// 特殊情况
if (arr[0] == "0" )
return "0";
string res = "";
for(auto s:arr) {
res += s;
}
return res;
}
};