JianZhiOffer_p33_把数组排成最小的数

输入一个正整数数组,将数组中各个数字连成一个数,输出所有可能的数字中最小的那个数。

举个栗子:
输入: 3,32,321
输出: 321323

最直观的做法是穷举所有排列所组成的数字,再从中找出最小的,该解法由于要穷举所有排列,所以复杂度至少为O(n!)。

有一种O(n*logn)的解法是,先对数组中数字按从小到大的顺序排序,再将数组中数字连接起来即为最小的数。

这里需要注意两点:

  1. 排序过程中,按递增顺序排列后得到的数字不一定是最小值。
    比如,3、32、321连接起来是332321并不是最小值,而321323才是所要求的最小值。所以这里需要改变排序规则,新规则必须使得排序后数字连接起来是最小的,在该例中,新规则排序后结果应该为321、32、3.
    新规则为:对于a,b两个数,将二者连接起来,若ab < ba,说明a在前b在后的排列所得到的数比较小。则认为a“小于”b,因此将a排在b前。(由于排序过程中会使用stl中的sort函数,因此时间复杂度为O(n*logn))
  2. 在将两个整数连接起来时,如果这两个整数比较大,则可能出现连接后数字超过整数范围的情况。因此考虑使用字符串来保存连接后数据。

代码为:

class Solution {
public:
    string PrintMinNumber(vector<int> numbers) {
        int n = numbers.size();
        if (n < 1) {return "";}
        if (n == 1) {return int2str(numbers[0]);}
        string s = "";
        sort(numbers.begin(),numbers.end(),mycompare);
        for (auto num:numbers) {
            s += int2str(num);
        }
        return s;
    }
    static bool mycompare(const int &a, const int &b) {
        string s1 = int2str(a) + int2str(b);
        string s2 = int2str(b) + int2str(a);
        return (s1<s2);
    }
    static string int2str(int n) {
        stringstream ss;
        string str;
        ss << n;
        ss >> str;
        return str;
    }
};

解法二:

先将数组按从小到大排序,再遍历数组,按照“如果ab < ba,那么a排在b前”的规则,将数组中数字连接成一个数字,该数即为数组中数字所能排成的最小的数。

代码二:

class Solution {
public:
    string PrintMinNumber(vector<int> numbers) {
        int n = numbers.size();
        if (n < 1) {return "";}
        if (n == 1) {return int2str(numbers[0]);}
        string s = "";
        sort(numbers.begin(),numbers.end());  // !!
        s += int2str(numbers[0]);
        for(int i=1; i<n; ++i) {
            string s1 = s + int2str(numbers[i]);
            string s2 = int2str(numbers[i]) + s;
            s = strcmp(s1.c_str(),s2.c_str()) > 0 ? s2 : s1;
        }
        return s;
    }
    string int2str(int n) { //?这里为什么不用static也可以?
        stringstream ss;
        string str;
        ss << n;
        ss >> str;
        return str;
    }
};

有个问题!
3、32、329 排成的最小数字应该是:323293
为什么这些代码输出的结果都是:323329 ??!!
牛客网上以上两个代码却都可以ac,而其他网友的代码对于3、32、329也输出的是323329?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值