Leetcode (8) Largest Number (剑指offer 33题 把数组排成最小的数)

题目描述

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.

本题的要求是给一个数组,要求根据数组的元素组成一个新的数,使该数最大。剑指offer上也有一样的题目,不过书上要求的是排成最小的数,其实这两个是一样一样的。

解题思路

根据题目的要求,相当于要对数组中的数字进行排序,这里的排序不能简单的按照数字的大小去排序,比如 30>9 但是组合之后 309 显然要比 903 小。所以更类似于一个由高位向低位的排序。博主最初的思路是按照基数排序(Radix Sort)的方法去实现,但是这样做很是麻烦(熟悉《算法导论》的同学应该知道,基数排序也是从低位往高位进行排序的,且数字的长度是一样的)。

但是根据博主之前的分析,有童鞋应该就已经想到了,那对于两个数字的大小我们根据他们组合后的结果进行比较久okay了呀。就像上面说的根据309 < 903排序结果应该是30 < 9(。。。这是个奇葩的小于号,童鞋们懂就好了。。。)。在有了上述思路之后,我们只用把整个数组进行一次排序,再按照从大到小的顺序把所有字符串串起了问题就解决了。

这里使用了sort()函数,并自定义比较的函数。

bool compare_str(const string& s1, const string& s2)
{
    string sa = s1 + s2;
    string sb = s2 + s1;

    return sa > sb;
}
class Solution {
public:
    string largestNumber(vector<int> &num) {
        vector<string> str;     
        for (size_t i = 0; i != num.size(); ++i)
        {
            stringstream ss;
            ss << num[i];
            str.push_back(ss.str());
        }

        sort(str.begin(), str.end(), compare_str);

        if (str.size() > 0 && str[0] == "0")
        {
            return "0";
        }

        string r;
        for (size_t i = 0; i != str.size(); ++i)
            r.append(str[i]);

        return r;
    }
};

剑指offer的进一步解释(to-do)

上面的思路跟剑指offer中提供的是一样的,但是剑指offer中提供了进一步的分析。上面的算法中,我们自己定义了一个比较两个数字大小的函数,剑指offer上证明了这种新定义的正确性(自反性、对称性、传递性以及得到的结果为最小数)。

你可能感兴趣的:(C++,每天编程一小时)