可视化图解算法62:组合总和

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

2. 解题思路

组合总和问题可以通过回溯算法完成。

回溯算法模板

对应的思路如下:

62-1

如果文字描述的不太清楚,你可以参考视频的详细讲解。

3. 编码实现

核心代码如下:

func combinationSum(candidates []int, target int) [][]int {
	result = make([][]int, 0)
	path = make([]int, 0)
	sort.Ints(candidates)
	backtracking(candidates, target, 0)
	return result
}
func backtracking(candidates []int, target int, start int) {
	// 2.递归终止条件:当目标和为0时,找到一个组合
	if target == 0 {
		//2.1 存放结果
		tmp := make([]int, len(path))
		copy(tmp, path)
		result = append(result, tmp)
		//2.2 返回
		return
	}
	//3.剪枝:如果目标和已经小于0,则停止当前分支
	if target < 0 {
		return
	}

	//1.选择:在本层集合中遍历元素
	for i := start; i < len(candidates); i++ {
		//1.1 处理节点(添加当前数字到路径中)
		path = append(path, candidates[i])
		// 1.2 递归 (递归调用,目标值减去当前数字)
		backtracking(candidates, target-candidates[i], i)
		//1.3 回溯,撤销选择
		path = path[:len(path)-1]
	}
}

var (
	result [][]int //结果集
	path   []int
)

具体完整代码你可以参考下面视频的详细讲解。

4.小结

组合总和问题可以通过回溯算法完成。在本层集合中遍历元素: 处理节点,将当前数字添加到路径中;递归调用,目标值减去当前值;回溯,撤销选择(移除当前数字,以便尝试其他组合)。

分割线

《数据结构与算法》深度精讲课程正式上线啦!7 大核心算法模块全解析:

  ✅   链表

  ✅   二叉树

  ✅   二分查找、排序

  ✅   堆、栈、队列

  ✅   回溯算法

  ✅   哈希算法

  ✅   动态规划

无论你是备战笔试面试、提升代码效率,还是突破技术瓶颈,这套课程都将为你构建扎实的算法思维底座。🔥立即加入学习打卡,与千名开发者共同进阶!

对于LeetCode数据结构与算法,我们总结了一套【可视化+图解】方法,依据此方法来解决相关问题,算法变得易于理解,写出来的代码可读性高也不容易出错。具体也可以参考视频详细讲解。

今日佳句:问君归期未有期,巴山夜雨涨秋池。

posted @ 2025-09-25 15:42  好易学数据结构  阅读(10)  评论(0)    收藏  举报