LeetCode题目笔记——1798. 你能构造出连续值的最大数目

题目描述

你能构造出连续值的最大数目 - 给你一个长度为 n 的整数数组 coins ,它代表你拥有的 n 个硬币。第 i 个硬币的值为 coins[i] 。如果你从这些硬币中选出一部分硬币,它们的和为 x ,那么称,你可以 构造 出 x 。

请返回从 0 开始(包括 0 ),你最多能 构造 出多少个连续整数。

你可能有多个相同值的硬币。

 

示例1:

输入:coins = [1,3]
输出:2
解释:你可以得到以下这些值:

  • 0:什么都不取 []
  • 1:取 [1]
    从 0 开始,你可以构造出 2 个连续整数。

示例 2:

输入:coins = [1,1,1,4]
输出:8
解释:你可以得到以下这些值:

  • 0:什么都不取 []
  • 1:取 [1]
  • 2:取 [1,1]
  • 3:取 [1,1,1]
  • 4:取 [4]
  • 5:取 [4,1]
  • 6:取 [4,1,1]
  • 7:取 [4,1,1,1]
    从 0 开始,你可以构造出 8 个连续整数。

示例 3:

输入:nums = [1,4,10,3,1]
输出:20

 

提示:

  • coins.length == n
  • 1 <= n <= 4 * 104
  • 1 <= coins[i] <= 4 * 104

题目链接

题目难度——中等

方法一:贪心

  这是一道考察思维的题目,数据量有点大,所以暴力解法肯定不行,不过如果时间允许的话,暴力解法也是可以的。先记下暴力的思路:首先将数组按升序排序,让x从1开始,对每个x,从数组最后往前遍历,如果当前元素等于x,说明找到一个,继续下一个x;如果当前元素小于x,说明需要加上前面的小一点的元素才能构成x,继续循环往前遍历,每次加元素,等于x时结束当前循环,大于x时减掉刚加的那个元素,如果遍历完都无法构成x,就退出整个循环,返回答案;如果当前元素大于x,继续往前。

  暴力的时间复杂度最坏情况下是O(N3),所以我么需要另辟蹊径。首先将数组升序排序,初始化res=1,遍历数组,对每个银币x,如果我们能构造出[0, x]这个区间中的数,再来一个数y,如果y大于当前答案,说明无论如何我们都不能构造出y,例如当coins=[0,1,2,3]时,我们能构造出[0,6]这7个整数,如果下一个硬币x=8,我们无法构造出7,不能满足题目条件,所以可以写成下面的代码:

代码

class Solution {
public:
    int getMaximumConsecutive(vector<int>& coins) {
        int n = coins.size();
        sort(coins.begin(), coins.end());
        int res = 1;
        for(auto c: coins){
            if(c > res){
                break;
            }
            res += c;
        }
        return res;
    }
};

在这里插入图片描述

class Solution:
    def getMaximumConsecutive(self, coins: list[int]) -> int:
        coins.sort()
        res = 1
        for c in coins:
            if c > res:
                break
            else:
                res += c
        return res

暴力代码(参考)

class Solution:
    def getMaximumConsecutive(self, coins: list[int]) -> int:
        n = len(coins)
        coins.sort()
        x = 1
        res = 1
        while True:
            done = True
            for i in range(n - 1, -1, -1):
                if coins[i] == x:
                    res += 1
                    done = False
                    break
                elif coins[i] < x:
                    tmp = coins[i]
                    find = False
                    for j in range(i - 1, -1, -1):
                        tmp += coins[j]
                        if tmp == x:
                            res += 1
                            done = False
                            find = True
                            break
                        elif tmp > x:
                            tmp -= coins[j]
                    if find:
                        break
                else:
                    continue
            
            x += 1
            if done:
                break
        return res

总结

  暴力方法时间复杂度来到了O(N3),空间是O(1),第二种方法时间是O(N),空间是O(1)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值