leetcode 39. 组合总和

109 阅读2分钟

[toc] leetcode 39. 组合总和

题目描述

  1. 组合总和

给你一个 无重复元素 的整数数组 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

回溯:

核心思想:逐步向下确定每一个位的数据,直到没有可用的数据或者满足条件

  1. 定义一个数x记录相加的值,能取数组中n[i]的条件是x+n[i]<=target,
  2. 如果满足记录条件就将该数记录进临时结果数组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多平台发布