英文原文
Given an array of distinct integers nums
and a target integer target
, return the number of possible combinations that add up to target
.
The answer is guaranteed to fit in a 32-bit integer.
Example 1:
Input: nums = [1,2,3], target = 4 Output: 7 Explanation: The possible combination ways are: (1, 1, 1, 1) (1, 1, 2) (1, 2, 1) (1, 3) (2, 1, 1) (2, 2) (3, 1) Note that different sequences are counted as different combinations.
Example 2:
Input: nums = [9], target = 3 Output: 0
Constraints:
1 <= nums.length <= 200
1 <= nums[i] <= 1000
- All the elements of
nums
are unique. 1 <= target <= 1000
Follow up: What if negative numbers are allowed in the given array? How does it change the problem? What limitation we need to add to the question to allow negative numbers?
中文题目
给你一个由 不同 整数组成的数组 nums
,和一个目标整数 target
。请你从 nums
中找出并返回总和为 target
的元素组合的个数。
题目数据保证答案符合 32 位整数范围。
示例 1:
输入:nums = [1,2,3], target = 4 输出:7 解释: 所有可能的组合为: (1, 1, 1, 1) (1, 1, 2) (1, 2, 1) (1, 3) (2, 1, 1) (2, 2) (3, 1) 请注意,顺序不同的序列被视作不同的组合。
示例 2:
输入:nums = [9], target = 3 输出:0
提示:
1 <= nums.length <= 200
1 <= nums[i] <= 1000
nums
中的所有元素 互不相同1 <= target <= 1000
进阶:如果给定的数组中含有负数会发生什么?问题会产生何种变化?如果允许负数出现,需要向题目中添加哪些限制条件?
通过代码
高赞题解
解题思路
常见的背包问题有1、组合问题。2、True、False问题。3、最大最小问题。
以下题目整理来自大神CyC,github地址:
github
我在大神整理的基础上,又做了细分的整理。分为三类。
1、组合问题:
377. 组合总和 Ⅳ
494. 目标和
518. 零钱兑换 II
2、True、False问题:
139. 单词拆分
416. 分割等和子集
3、最大最小问题:
474. 一和零
322. 零钱兑换
组合问题公式
dp[i] += dp[i-num]
True、False问题公式
dp[i] = dp[i] or dp[i-num]
最大最小问题公式
dp[i] = min(dp[i], dp[i-num]+1)或者dp[i] = max(dp[i], dp[i-num]+1)
以上三组公式是解决对应问题的核心公式。
当然拿到问题后,需要做到以下几个步骤:
1.分析是否为背包问题。
2.是以上三种背包问题中的哪一种。
3.是0-1背包问题还是完全背包问题。也就是题目给的nums数组中的元素是否可以重复使用。
4.如果是组合问题,是否需要考虑元素之间的顺序。需要考虑顺序有顺序的解法,不需要考虑顺序又有对应的解法。
接下来讲一下背包问题的判定
背包问题具备的特征:给定一个target,target可以是数字也可以是字符串,再给定一个数组nums,nums中装的可能是数字,也可能是字符串,问:能否使用nums中的元素做各种排列组合得到target。
背包问题技巧:
1.如果是0-1背包,即数组中的元素不可重复使用,nums放在外循环,target在内循环,且内循环倒序;
for num in nums:
for i in range(target, nums-1, -1):
2.如果是完全背包,即数组中的元素可重复使用,nums放在外循环,target在内循环。且内循环正序。
for num in nums:
for i in range(nums, target+1):
3.如果组合问题需考虑元素之间的顺序,需将target放在外循环,将nums放在内循环。
for i in range(1, target+1):
for num in nums:
代码
class Solution:
def combinationSum4(self, nums: List[int], target: int) -> int:
if not nums:
return 0
dp = [0] * (target+1)
dp[0] = 1
for i in range(1,target+1):
for num in nums:
if i >= num:
dp[i] += dp[i-num]
return dp[target]
以上是我对背包问题的总结,希望对你有帮助。要是觉得不错,点个赞吧。
欢迎关注我的公众号:
润山带你分析数据
一个给职场人分享数据分析知识的公众号。里面也有算法刷题的干货哦~
统计信息
通过次数 | 提交次数 | AC比率 |
---|---|---|
69552 | 135935 | 51.2% |
提交历史
提交时间 | 提交结果 | 执行时间 | 内存消耗 | 语言 |
---|
相似题目
题目 | 难度 |
---|---|
组合总和 | 中等 |