剑指Offer45.把数排成最小的数

  • 剑指Offer45.把数排成最小的数

  • 题目:
    把一个vector,使其每个元素值接起来得到的值最小;
    考虑大数,需要用string保存结果;

  • 思路:
    1.指定一个排序规则:时间O(nlogn),最坏O(n^2);空间O(logn),最坏O(n)

//写法1:
class Solution {
public:
    string minNumber(vector<int>& nums) {
        string res;
        if (nums.empty()) return res;

        auto lamb = [](int a, int b)->bool {
            auto as = to_string(a), bs = to_string(b);
            return as + bs < bs + as;
        };
        sort(nums.begin(), nums.end(), lamb);//这里需要转一次
        for (auto x : nums) res+= to_string(x);//这里也需要转一次

        return res;
    }
};
//写法2:为了避免多次将int转乘string的操作,因此开头把vector<int>转成vector<string>,虽浪费了空间,但节省了时间,每个int只需转一次string即可;
class Solution {
public:
    string minNumber(vector<int>& nums) {
        string res;
        if (nums.empty()) return res;

        vector<string> vs;
        for (auto x : nums) vs.push_back(to_string(x));
        sort(vs.begin(), vs.end(), [](string& a, string& b){ return a + b < b + a; });
        for (auto x : vs) res+= x;

        return res;
    }
};

2.手写快排:O(nlogn),O(1)
把str1 + str2 < str2 + str1的排序规则应用在快排上;

class Solution {
public:
    void quickSort(vector<string>& strs, int left, int right) {
        if (left >= right) return;
        int l = left;
        int r = right;
        string pivot = strs[left];
        while (l < r) {
            while (l < r && strs[r] + pivot >= pivot + strs[r]) r--; //右哨兵找小的
            while (l < r && strs[l] + pivot <= pivot + strs[l]) l++; //左哨兵找大的
            if (l < r) swap(strs[l], strs[r]);
        }
        swap(strs[l], strs[left]);
        quickSort(strs, left, l - 1);
        quickSort(strs, l + 1, right);
    }
    string minNumber(vector<int>& nums) {
        vector<string> strs;
        for (int num : nums) strs.push_back(to_string(num));
        quickSort(strs, 0, strs.size() - 1);
        string ans;
        for (string str : strs) ans += str;
        return ans;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值