[剑指Offer]:把数组排成最小的数

162 阅读1分钟

文章目录


题目描述

输入一个非负整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。

示例 1:

输入: [10,2]
输出: "102"

示例 2:

输入: [3,30,34,5,9]
输出: "3033459"

提示:

0 < nums.length <= 100

说明:

  • 输出结果可能非常大,所以你需要返回一个字符串而不是整数
  • 拼接起来的数字可能会有前导 0,最后结果不需要去掉前导 0

题解思路

不管有多少个数,也不管这些数各自分别是几位数(个位 / 十位 / 百位 / …),我们的判断方法只有一个。那就是先比较最高位,按照从小到大排即可。具体步骤如下:

  1. 先比较这些数各自的最高位,按从小到大排。比如 “1”、“32”、“100”,我们通过比较最高位可以排出:一开始是 “1” 或 “100”,然后是 “32”。

  2. 如果遇到了最高位数字相同的情况,比如上面的 “1” 和 “100”,我们自定义比较方法:比较 字符串 1 + 字符串 2 与 字符串 2 + 字符串 1 的大小,返回小的那个。

    • 在这里我们有 “1” + “100” = “1100” 和 “100” + “1” = “1001”。
    • 因为 “1001” < “1100”,所以我们知道应该把 “100” 放第一位,“1” 放第二位,“32” 还是在最后。
  3. 假如最高位没有相同数字,那么根据最高位的排序直接就已经排好了。

代码实现:

class Solution {
public:
    string minNumber(vector<int>& nums) {
        if(nums.size() == 1) return to_string(nums[0]);

        vector<string> v;
        string res;
        for(auto i : nums) v.push_back(to_string(i));
        sort(v.begin(), v.end(), strCompare);   // 自定义 strCompare 函数
        for(auto i : v) res += i;
        return res;
    }

    static bool strCompare(const string& s1, const string& s2){ // 注意 static
        string add1 = s1 + s2;
        string add2 = s2 + s1;
        return add1 < add2;
    }
};

不加static为什么会报错?

sort中的比较函数compare要声明为 静态成员函数全局函数,不能作为普通成员函数,否则会报错。 因为:

  • 非静态成员函数是依赖于具体对象的,而std::sort这类函数是全局的,因此无法再sort中调用非静态成员函数。
  • 静态成员函数或者全局函数是不依赖于具体对象的, 可以独立访问,无须创建任何对象实例就可以访问。同时静态成员函数不可以调用类的非静态成员。

如有帮助到您,可以多多点赞、评论鼓励哟~~~