leetcode中的最大数字:有人能解释为什么这个方法有效吗

Largest Number from leetcode : can someone explain why this method works?

本文关键字:为什么 能解释 方法 有效 数字 leetcode      更新时间:2023-10-16

这是leetcode 的问题

给定一个非负整数列表,将它们排列为形成最大的数字。

例如,给定[3,30,34,5,9],形成的最大数量为9534330.

这是我见过的最简单的解决方案:

class Solution {
public:
    string largestNumber(vector<int> &num) {
        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; });
        string res;
        for(auto s:arr)
            res+=s;
        while(res[0]=='0' && res.length()>1)
            res.erase(0,1);
        return  res;
    }
};

我很困惑为什么这种方法有效。。有人能证明这个方法吗?

首先要注意的是,用向量的所有元素形成的每个数字都有相同数量的数字。这就是为什么我们可以对字符串使用字典排序的原因。

因此,我们可以简单地列出所有可能的串联,并从中选择最大的

用于排序的字符串比较将上述事实用于向量中2个元素的特殊情况。因此,我们可以修改天真的实现,首先使用这个比较器搜索最大的to元素,将它们连接起来,然后用大小减少了1的向量重复(新连接的元素也包含在新向量中)。但话说回来,我们会选择那个新连接的元素和剩下的最大元素继续。如果我们不选择那个新串联的元素,那么我们一开始就不会选择向量的两个最大元素。所以我们按照递减的顺序一个接一个地挑选元素。这就是为什么首先应用排序。

您必须对数组成员的所有可能组合进行优化。例如3303459、9534303、9353430、93534303等。。。。所以,一开始你必须对它们进行排序,然后组合成一个字符串。对于排序,你不能只比较3和30,你必须比较它们的合并值303和330,如果你只用3检查像30这样的成员,你会有303,但实际上在这个比较中你应该有330,因为330>303,这就是为什么应该比较s1 + s2s2 + s1

关于while循环,可能的吮吸测试用例[0,0,0,0],对于这种情况,将生成这样的字符串"0000",但这不是正常数字,我们必须删除除最后一个之外从左边开始的所有0,以获得正常数字"0"