[toc] leetcode 39. 组合总和
题目描述
- 组合总和
给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。
candidates 中的 同一个 数字可以 无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的。
对于给定的输入,保证和为 target 的不同组合数少于 150 个。
示例 1:
输入:candidates = [2,3,6,7], target = 7 输出:[[2,2,3],[7]] 解释: 2 和 3 可以形成一组候选,2 + 2 + 3 = 7 。注意 2 可以使用多次。 7 也是一个候选, 7 = 7 。 仅有这两种组合。 示例 2:
输入: candidates = [2,3,5], target = 8 输出: [[2,2,2,2],[2,3,3],[3,5]] 示例 3:
输入: candidates = [2], target = 1 输出: []
提示:
1 <= candidates.length <= 30 2 <= candidates[i] <= 40 candidates 的所有元素 互不相同 1 <= target <= 40 通过次数738,611提交次数1,020,608
解题思路
法1
回溯:
核心思想:逐步向下确定每一个位的数据,直到没有可用的数据或者满足条件
- 定义一个数x记录相加的值,能取数组中n[i]的条件是x+n[i]<=target,
- 如果满足记录条件就将该数记录进临时结果数组r[]中,,如果等于target,就将临时数组添加进返回数组中,如果不是就继续递归执行函数直到没有可用的数据或者满足条件
注意:为避免数据重复,确定数据时只能为单向,就是说每次递归的num都在不断缩短(也可能不变),变化的条件就是该位置确定数值在n中的 位置有关,如果确定该数在n中为j为,那么递归时n=n[j:]
比如n=[2,5,3,8]target=8
第一位可以为2,5,3,8 其中8满足条件加入append进返回数组
当第一位为2时,第二位可以为2,3,5因为8+2>target所以不能为8
同时当第一位为5时第二位只能为3,因为之前的2不能使用,
同理当第一位为3时就没有可以确定的第二位,2,5在3位置之前不能用,如果用了5,也会与之前的数据发生数据冲突
这样逐渐确定每个位置的数据直到满足条件,返回使用满足条件的数组
- 时间复杂度(O(n))
- 空间复杂度(O(n))
执行结果
法1
递归的方式进行回溯搜索。
在每一层递归中,选择一个候选数字加入组合,然后递归调用自身,继续向下搜索。
当组合的和等于目标数时,将该组合加入结果集中。
如果和大于目标数,或者已经遍历完所有的候选数字,则回溯到上一层,选择其他的候选数字。
func combinationSum(candidates []int, target int) [][]int {
result := make([][]int, 0)
combination := make([]int, 0)
backtrack(candidates, target, 0, combination, &result)
return result
}
func backtrack(candidates []int, target int, start int, combination []int, result *[][]int) {
if target == 0 {
// 找到一个满足条件的组合
// 需要将组合复制一份,避免后续修改影响到已加入结果集中的组合
temp := make([]int, len(combination))
copy(temp, combination)
*result = append(*result, temp)
return
}
for i := start; i < len(candidates); i++ {
if candidates[i] <= target {
combination = append(combination, candidates[i])
backtrack(candidates, target-candidates[i], i, combination, result)
combination = combination[:len(combination)-1] // 回溯,移除最后一个元素
}
}
}
题目描述 评论 (2.1k) 题解 (3.9k) 提交记录 执行结果: 通过 显示详情 查看示例代码 添加备注
执行用时: 0 ms , 在所有 Go 提交中击败了 100.00% 的用户 内存消耗: 2.8 MB , 在所有 Go 提交中击败了 44.88% 的用户 通过测试用例: 160 / 160 炫耀一下:
本文由mdnice多平台发布