力扣(LeetCode)1753. 移除石子的最大得分(C++\C)

贪心+模拟

贪心思路 : 循环从石子数量最多的两堆取石子,直到有两堆以上(含两堆)空石子,维护取子次数,即是答案。贪心的正确性,暂无数学证明。直觉来看,这么做是对的。

CPP

class Solution {
public:
    int maximumScore(int a, int b, int c) {
        int f[3] = {a,b,c};
        sort(f,f+3);
        int ans = 0;
        while(f[0]||f[1]){
            ans++;
            f[1]--,f[2]--;
            sort(f,f+3);
        }
        return ans;
    }
};

C

int cmp(const void *a,const void *b){
    return *(int*)a-*(int*)b;
}
int maximumScore(int a, int b, int c){
    int f[3] = {a,b,c};
    qsort(f,3,sizeof(int),cmp);
    int ans = 0;
    while(f[0]||f[1]){
        ans++;
        f[1]--,f[2]--;
        qsort(f,3,sizeof(int),cmp);
    }
    return ans;
}
  1. 时间复杂度 : O ( m ) O(m) O(m) m m m 是最多石子的那一堆的石子数量, 最坏时间复杂度 O ( m ) O(m) O(m)
  2. 空间复杂度 : O ( 1 ) O(1) O(1) , 只使用常量级空间 。
贪心+数学

a , b , c a,b,c a,b,c 存入数组 f f f 按升序排序。如果 f [ 0 ] + f [ 1 ] < = f [ 2 ] f[0]+f[1]<=f[2] f[0]+f[1]<=f[2] ,根据贪心思路,每次取最大两堆的石子,就是循环从 f [ 2 ] f[2] f[2] m a x ( f [ 0 ] , f [ 1 ] ) max(f[0],f[1]) max(f[0],f[1]) 取石子。取石子的次数 = f [ 0 ] + f [ 1 ] =f[0]+f[1] =f[0]+f[1]

如果 f [ 0 ] + f [ 1 ] > f [ 2 ] f[0]+f[1]>f[2] f[0]+f[1]>f[2] ,可以想象,这种情况一定可以最大限度的取完所有石子——①三堆都取完 ②某一堆剩 1 1 1 个石子,其他两堆取完。根据贪心思路,每次取最大两堆,它的终止条件就是①或②。取石子的次数,只和终止状态下,三堆剩余的石子数有关。我们可以随便取,只要达到①或②的终止状态,就是最优解法。

考虑先从 f [ 2 ] f[2] f[2] m a x ( f [ 0 ] , f [ 1 ] ) max(f[0],f[1]) max(f[0],f[1]) 取石子, f [ 2 ] f[2] f[2] 一定会被取完,因为 f [ 0 ] + f [ 1 ] > f [ 2 ] f[0]+f[1]>f[2] f[0]+f[1]>f[2] 。取完 f [ 2 ] f[2] f[2] 时, f [ 0 ] f[0] f[0] f [ 1 ] f[1] f[1] 的差值不大于 1 1 1 ,接着从 f [ 0 ] f[0] f[0] f [ 1 ] f[1] f[1] 中取石子,最后也能达到三堆都取完或者某一堆剩 1 1 1 个石子,其他两堆取完的状态 。取石子的次数 = ( f [ 0 ] + f [ 1 ] + f [ 2 ] ) ÷ 2 =(f[0]+f[1]+f[2])\div 2 =(f[0]+f[1]+f[2])÷2

CPP

class Solution {
public:
    int maximumScore(int a, int b, int c) {
        int f[3] = {a,b,c};
        sort(f,f+3);
        if(f[0]+f[1]<=f[2]) return f[0] + f[1];
        return f[0]+f[1]+f[2]>>1;
    }
};

C

int cmp(const void *a,const void *b){
    return *(int*)a-*(int*)b;
}
int maximumScore(int a, int b, int c){
    int f[3] = {a,b,c};
    qsort(f,3,sizeof(int),cmp);
    if(f[0]+f[1]<=f[2]) return f[0] + f[1];
    return f[0]+f[1]+f[2]>>1;
}
  1. 时间复杂度 : O ( 1 ) O(1) O(1) , 只进行常量次计算 。
  2. 空间复杂度 : O ( 1 ) O(1) O(1) , 只使用常量级空间 。
AC

AC
AC

致语
  • 理解思路很重要!
  • 欢迎读者在评论区留言,墨染看到就会回复的。
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

清墨韵染

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值