PAT A1038 Recover the Smallest Number 排成最小的数 (贪心)

先说一下思路 不太容易去想到就是用字符串进行比较

我们需要自己手写一个排序函数,函数既可以直接提前实现 也可以定义后再进行实现

可以用贪心的思想解决。

对于所有的数字片段,我们需要确定任意两个数字片段之间的先后顺序,使得组成的数字最小。

我们可以考虑对于两个数字串 a 和 b,如何确定它们的先后顺序。

假设 a 和 b 的长度分别为 la 和 lb,我们对它们进行拼接,得到两个数字 ab 和 ba。如果 ab < ba,那么我们就确定 a 需要排在 b 的前面,否则就确定 b 需要排在 a 的前面。(例如32,321,拼接后分别是32321、32132,所以321需要排在前面)

按照这种方式对所有的数字串进行排序之后,再将它们依次拼接起来,就可以得到最小的数字。

需要注意的一点是,如果最终的数字以 0 开头,那么需要去掉前导零。

时间复杂度

排序的时间复杂度为 O(nlogn),拼接的时间复杂度为 O(n),因此总时间复杂度为 O(nlogn)。

贴一下ac代码

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int main()
{
    int n,k=0;
    cin>>n;
    string str[n+2];
    for(int i=0;i<n;++i) cin>>str[i];
    sort(str,str+n,[](string a,string b)
         {
        return a+b<b+a;
    });//直接再sort排序中进行实现 ,也可以单独写一个比较函数 看个人喜好 我主要喜欢代码剪简短一点嘿嘿嘿
    string res;
    for(int i=0;i<n;++i) res+=str[i];
    while(k+1<res.size()&&res[k]=='0') k++;//去掉前导零
    cout<<res.substr(k);//substr超级好用 大家去学一下
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值