leetcode 39. 组合总和 golang实现

本文深入探讨了在给定无重复元素数组和目标数的情况下,寻找所有可能的组合使数字和为目标数的算法。采用回溯法实现,通过示例详细讲解了如何避免重复组合,确保所有数字均为正整数,且解集不包含重复组合。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

描述
给定一个无重复元素的数组candidates和一个目标数target,找出candidates中所有可以使数字和为target的组合。

candidates中的数字可以无限制重复被选取。

说明:

所有数字(包括target)都是正整数。
解集不能包含重复的组合。
示例1:

输入: candidates = [2,3,6,7], target = 7,
所求解集为:
[
  [7],
  [2,2,3]
]
示例 2:

输入: candidates = [2,3,5], target = 8,
所求解集为:
[
 [2,2,2,2],
 [2,3,3],
 [3,5]
]
思路
回溯法
1. 每次遍历candidates得到的candidate 即为一个分支 取临时变量cur + candidate <= target 时 可继续向下遍历
2. 剪枝条件为cur == target
需要注意: 
1.每次继续更深度递归时,candidate 要大于路径中上一个candidate 否则会有重复的结果 比如例1 结果 [[2,2,3], [2,3,2], [3,2,2], [7]]
2. 由于golang 切片底层实现的原因 要用一个临时变量tmpRet保存结果 多个子节点公用父节点的切片 会出现子节点修改其他子节点的问题
实现
func combinationSum(candidates []int, target int) [][]int {
	ret := make([][]int, 0)
	if target == 0 || len(candidates) == 0 {
		return ret
	}
	curRet := make([]int, 0)

	ret = combinationSumBackTracking(0, curRet, candidates, target, ret)

	return ret
}

func combinationSumBackTracking(cur int, curRet []int, candidates []int, target int, ret [][]int) [][]int {
	if cur == target {
		ret = append(ret, curRet)
		return ret
	}

	var pre int
	if len(curRet) > 0 {
		pre = curRet[len(curRet)-1]  //pre 为路径的上一个candidate
	}
	for _, candidate := range candidates {
		if cur+candidate <= target && candidate >= pre {
			tmpCurRet := make([]int, 0)// 注意2
			tmpCurRet = append(tmpCurRet, curRet...)
			tmpCurRet = append(tmpCurRet, candidate)

			ret = combinationSumBackTracking(cur+candidate, tmpCurRet, candidates, target, ret)

		}
	}

	return ret
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值