chapter_backtracking/subset_sum_problem/ #559
Replies: 22 comments 25 replies
-
实在是太有石粒辣,感觉这种问题的难点在于剪枝操作怎么写,遍历递归前需要提前考虑的东西很多 |
Beta Was this translation helpful? Give feedback.
-
根本不是人能想出来的,一环套一环,四环又四环,四环外边是五环。 |
Beta Was this translation helpful? Give feedback.
-
重复元素的情况,剪枝四的 i > start 是不是应该改为 i > 0 啊,不然无法剪枝n个元素之和等于目标值的情况。 还有个疑问是可以排序时去重代替剪枝四吗? |
Beta Was this translation helpful? Give feedback.
-
subset_sum_ii.js
需要调整为: i+1 --> i ,不然不满足每个元素可被选取多次的条件~ |
Beta Was this translation helpful? Give feedback.
-
请教,13.3.2中->“实现方式比较巧妙:由于数组是已排序的,因此相等元素都是相邻的”,题目没有说是给定有序数组nums啊?为什么默认就以有序数组来处理了呢? |
Beta Was this translation helpful? Give feedback.
-
关于重复情况的剪枝4,其实跟全排列问题中的 def backtrack(
state: list[int], target: int, choices: list[int], start: int, res: list[list[int]]
):
"""回溯算法:子集和 II"""
# 子集和等于 target 时,记录解
if target == 0:
res.append(list(state))
return
# 遍历所有选择
# 剪枝二:从 start 开始遍历,避免生成重复子集
# 剪枝三:从 start 开始遍历,避免重复选择同一元素
duplicated = set[int]()
for i in range(start, len(choices)):
# 剪枝一:若子集和超过 target ,则直接结束循环
# 这是因为数组已排序,后边元素更大,子集和一定超过 target
if target - choices[i] < 0:
break
# 剪枝四:如果该元素重复,跳过
if choices[i] in duplicated:
break
# 尝试:做出选择,更新 target, start
state.append(choices[i])
# 进行下一轮选择
backtrack(state, target - choices[i], choices, i + 1, res)
# 回退:撤销选择,恢复到之前的状态
state.pop() 这样可以省去对数组进行排序。我理解的对吗? |
Beta Was this translation helpful? Give feedback.
-
考虑全排列的情况下,我这种改法是否会有问题?和原始的代码只有一个 slicing 的区别。
|
Beta Was this translation helpful? Give feedback.
-
个人愚见: 13.3.2题目:“给定数组包含重复元素,每个元素只可被选择一次”; 是否中间在增加一个案例: |
Beta Was this translation helpful? Give feedback.
-
13.3.2 考虑重复元素的情况 |
Beta Was this translation helpful? Give feedback.
-
老板,出书了嘛??有计划嘛?? |
Beta Was this translation helpful? Give feedback.
-
backtrack(state, target - choices[i], choices, i , res); |
Beta Was this translation helpful? Give feedback.
-
建议大佬 把相似的leetcode题目附上,让大家去练 |
Beta Was this translation helpful? Give feedback.
-
感觉回溯是枚举的另一实现 |
Beta Was this translation helpful? Give feedback.
-
第二项代码的state.pop()换成break会更好一点吗 |
Beta Was this translation helpful? Give feedback.
-
为什么13.3.2中剪枝过程能不像上一份一样用break而改用continue? |
Beta Was this translation helpful? Give feedback.
-
为什么要i>start,就跳过 |
Beta Was this translation helpful? Give feedback.
-
我有个建议,就是在subset_sum_ii.java这个文件里的 |
Beta Was this translation helpful? Give feedback.
-
我突然想到,最后一题,如果要求元素只能被选择一次,既然可以排序,那何不直接先去重,再回溯,岂不更秒。哈哈哈 |
Beta Was this translation helpful? Give feedback.
-
大佬把回溯讲得好清楚!!! |
Beta Was this translation helpful? Give feedback.
-
图13-11: |
Beta Was this translation helpful? Give feedback.
-
在图 13-14中,感觉第三层的第一个节点不应该出现,因为在第二轮选择中,-4^应该被剪枝4去掉。 |
Beta Was this translation helpful? Give feedback.
-
写了个自认为比较清晰的代码,如有错误,还请指正。 void backtrack(vector<int> &nums, vector<int> ¤t, int total, int target, vector<vector<int>> &result, int index)
{
if (total == target)
{ // 如果当前集合之和等于目标,则将当前集合加入结果集
result.push_back(current);
return;
}
for (int i = 0; i < nums.size(); ++i)
{
if (nums[i] + total > target || i < index || nums[i] == nums[i - 1]) continue;
// 如果超出边界、出现重复遍历以及重复元素,则跳过
current.push_back(nums[i]); // 将当前元素加入集合
backtrack(nums, current, total + nums[i], target, result, i); // 递归调用下一层
current.pop_back(); // 回溯到上一层,移除当前元素
}
} |
Beta Was this translation helpful? Give feedback.
-
chapter_backtracking/subset_sum_problem/
在动画与代码中掌握数据结构与算法
https://www.hello-algo.com/chapter_backtracking/subset_sum_problem/
Beta Was this translation helpful? Give feedback.
All reactions