贪心, 不需要理由 以力扣179.最大数为例

贪心, 每一步最优来实现最终结果最优。如果不用贪心, 一步一步枚举则会导致时间复杂度过高,导致超过了算法题的时间限制。但是贪心往往是比较难证明的,在面试或者竞赛中,就需要我们学会去猜想,大胆去实践,而不是把时间花在证明上。
如何去猜想,就需要在处理一小部分数据时,根据题目的意思使局部最优化,方法包括条件范化宽松化,条件分步走等,这需要我们在做题中不断积累。我们今天来以力扣179题来说明贪心如何去运用:

题目
给定一组非负整数 nums,重新排列每个数的顺序(每个数不可拆分)使之组成一个最大的整数。
注意:输出结果可能非常大,所以你需要返回一个字符串而不是整数。

示例:
输入:nums = [10,2]
输出:“210”

  1. 分析:这相当于一个给数字排列的问题,问题的关键的一小步是怎么确定两个数字之间的顺序, 如果确定了,那么下面就好做了。根据题目中合成最大数原则,可以泛化到两个数上,两个数就两种不同排列,很好比较大小, 那么整个数组就很好排序了。具体实现见代码:
  2. 技巧:本例中还有几个实用小技巧,比如:大数连接可以通过字符串相加,比较大小可以直接通过字符串比较,这样效率比较高。
class Solution {
public:
static int cmp(int a, int b){
    char ac[21], bc[21], temp[21];
    sprintf(ac, "%d", a);
    sprintf(bc, "%d", b);
    strcpy(temp, ac);
    strcat(ac, bc);
    strcat(bc, temp);
    //cout<<ac<<" ac"<<endl;
    //cout<<bc<<" bc"<<endl;
    return (strcmp(ac,bc)<0)?0:1;
}
string largestNumber(vector<int>& nums){
    string s("0");
    if(nums.size() == 0){
        return s;
    }
    int i = 0;
    for(i = 0; i < nums.size();i++){
        if(nums[i]!= 0){
            break;
        }
    }
    if(i == nums.size()){
        return s;
    }
    sort(nums.begin(),nums.end(), cmp);
    string res("");
    for (int i = 0; i < nums.size();i++){
        //cout<<nums[i]<<" = nums["<<i<<"]"<<endl;
        res += to_string(nums[i]);
    }
    return res;
}
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值