题目描述
你能构造出连续值的最大数目 - 给你一个长度为 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)。