题目如下:
Given a list of non negative integers, arrange them such that they form the largest number.
For example, given [3, 30, 34, 5, 9], the largest formed number is 9534330.
Note: The result may be very large, so you need to return a string instead of an integer.
Credits:
Special thanks to @ts for adding this problem and creating all test cases.
分析如下:
先看几个例子
eg1. [0, 0, 0 , 0] -> 0
eg2. [1211, 12] -> 121211而不是121112。
所以可以考虑排序,而排序的根据(也就是比较函数的比较原理)不是这些数的值的相对大小,而是它们构成新的数的大小比较。
所以,虽然1211 > 12, 但是
"1211" + "12" = "121112",
“12” + "1211" = "121211",
"121112" < "121211"
所以从构成新的数的角度来看, "1211" < "12" 。
我的代码:
//13ms
struct {
bool operator()(string a, string b)
{
string c1 = a + b;
string c2 = b + a;
return c1 > c2;
}
} compareDigits;
class Solution {
public:
string largestNumber(vector<int> &num) {
if (num.size() == 0) return "";
vector<string> num_str;
for (int i = 0; i < num.size(); ++i) {
num_str.push_back(to_string(num[i]));
}
std::sort(num_str.begin(), num_str.end(), compareDigits);
string res1 = "";
for (int i = 0; i < num_str.size(); ++i)
res1 += num_str[i];
if (res1[0] == '0')
return "0";
else
return res1;
}
};
小结扩展:
1 比较函数的写法,注意比较函数中的等号的处理。
一开始的错误写法如下,
struct {
bool operator()(string a, string b)
{
string c1 = a + b;
string c2 = b + a;
for (int j = 0; j < c1.length(); ++j) {
if (c1[j] < c2[j])
return false;
else
//错误,这里的else必须只能表示">"不能表示">=" 。因为这里的比较函数是对"<"写的。"="和">"都是false。
return true;
}
return false;
}
} compareDigits;
修改后为,
struct {
bool operator()(string a, string b)
{
string c1 = a + b;
string c2 = b + a;
for (int j = 0; j < c1.length(); ++j) {
if (c1[j] < c2[j])
return false;
else if (c1[j] > c2[j])
return true;
}
return false; //"="的case, 因为operator()表示小于,所以">" 或者 "="都为false;
}
} compareDigits;
再简化一下,就是。
struct {
bool operator()(string a, string b)
{
string c1 = a + b;
string c2 = b + a;
return c1 > c2;
}
} compareDigits;
2 另外一种思路。
上面的思路是O(NlgN),下面看另外一种思路虽然是O(N²), 但也不错,挑玉米算法。
class Solution {
public:
string largestNumber(vector<int> &num) {
string str = "";
while(!num.empty())
{
int n = num.size();
int j = 0;
int vv = num[j];
for(int i=1;i!=n;i++){
int uu = num[i];
uu = num[i];
vv = num[j];
if(uu != vv)
if(to_string(uu)+to_string(vv)>to_string(vv)+to_string(uu)){
j=i; //j保持当前的"最大"string, "最大"在这里不是指它本身最大,而是指,如果它能够合成最大的数。
}
}
str += to_string(num[j]);
num.erase(num.begin()+j);
}
while(str[0]=='0'&&str.size()>1) str.erase(str.begin());
return str;
}
};