列表子集递归求和实现:寻找和为指定值的无重复子集
解决找和为目标值的不重复子集问题
嘿,看来你在找子集和的问题上卡壳了,我来帮你梳理下思路,给你一个可行的解决方案!
首先,你之前尝试的双向链表方法其实不太适配这个问题——子集和这类组合问题,用**回溯法(深度优先搜索)**会更直接高效,而且能轻松避免重复子集。先说说核心思路:
核心思路
- 排序去重:先把原列表排序,这样能方便我们跳过重复元素,避免生成如
[2,9]和[9,2]这种本质相同的子集(因为子集是无序的),同时也能在和超过目标值时提前剪枝。 - 回溯递归:递归地遍历每个元素,选择加入当前子集或者跳过,同时跟踪当前子集的和:
- 如果当前和等于目标值
v,就把这个子集加入结果列表; - 如果当前和已经超过
v,直接停止递归(因为所有元素都是正数,继续加只会更大); - 遇到重复元素时,跳过它,避免生成重复的子集。
- 如果当前和等于目标值
具体代码实现
下面是针对你需求的Python代码,我会加上详细注释:
def find_subsets_with_sum(nums, v): # 先排序,方便去重和剪枝 nums.sort() result = [] def backtrack(start, current_path, current_sum): # 找到符合条件的子集,加入结果 if current_sum == v: result.append(current_path.copy()) return # 和超过目标,直接剪枝 if current_sum > v: return for i in range(start, len(nums)): # 跳过重复元素,避免生成重复子集 if i > start and nums[i] == nums[i-1]: continue # 选择当前元素 current_path.append(nums[i]) # 递归,注意起始索引是i+1,避免重复选同一个元素 backtrack(i+1, current_path, current_sum + nums[i]) # 回溯,撤销选择 current_path.pop() backtrack(0, [], 0) return result # 测试你的示例 nums = [2,3,5,6,8,9,1] v = 11 print(find_subsets_with_sum(nums, v))
运行这段代码,你会得到符合预期的结果(因为子集无序,排序后格式统一,避免了重复):
[[1,2,8], [1,2,3,5], [1,3,6], [2,9], [3,8], [5,6]]
对你之前尝试的说明
你写的traverse函数其实只是用来统计双向链表的长度,和当前找子集和的需求不相关。双向链表的结构并不适合这类组合搜索问题,反而会增加复杂度,所以换用回溯法是更合适的选择。
内容的提问来源于stack exchange,提问作者Yslid
相关产品推荐
相关产品推荐

