This commit is contained in:
parent
4ec46c3dda
commit
2aee636736
@ -23,7 +23,7 @@ void backtrack(NodeState &node, vector<NodeState> &result, int para1, int para2,
|
|||||||
// 终止条件
|
// 终止条件
|
||||||
// 回溯法中的每个节点并不是真的树状节点,没有 `nullptr` ,因此用空指针来判断是否到了叶子结点并不合理,需要其它的一些方法来确定是否到达叶子节点,比如高度。
|
// 回溯法中的每个节点并不是真的树状节点,没有 `nullptr` ,因此用空指针来判断是否到了叶子结点并不合理,需要其它的一些方法来确定是否到达叶子节点,比如高度。
|
||||||
if (/* end condition */) {
|
if (/* end condition */) {
|
||||||
result.push_back(node);
|
/* update result */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,6 +51,10 @@ void backtrack(NodeState &node, vector<NodeState> &result, int para1, int para2,
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
回溯法的一个很重要的考点在于如何去重。去重有两种思路,一个是用哈希表记录每一层的使用情况,另一种是排序 + 判断,后者性能更好所以优先选择后者。
|
||||||
|
|
||||||
|
具体算法参考 [40. 组合总和 II](./combinations.html) 和 [491. 递增子序列](./subsets.html)
|
||||||
|
|
||||||
复杂度分析:
|
复杂度分析:
|
||||||
|
|
||||||
- 时间复杂度:最长路径长度 × 搜索树的节点数
|
- 时间复杂度:最长路径长度 × 搜索树的节点数
|
||||||
|
@ -129,3 +129,33 @@ if (i > 0 && candidates[i] == candidates[i - 1] && used[i - 1] == false)
|
|||||||
// 对 candidates 进行升序排序,这是为了进行剪枝
|
// 对 candidates 进行升序排序,这是为了进行剪枝
|
||||||
sort(candidates.begin(), candidates.end());
|
sort(candidates.begin(), candidates.end());
|
||||||
```
|
```
|
||||||
|
|
||||||
|
完整代码如下:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
void combinationSum2DFS(vector<int> &candidates, int target, int startIndex,
|
||||||
|
vector<int> &path, int sum, vector<bool> &used,
|
||||||
|
vector<vector<int>> &result) {
|
||||||
|
// 结束条件:总和等于 target 。不存在总和大于 target 的情况,因为已经被剪枝了
|
||||||
|
if (sum == target) {
|
||||||
|
result.push_back(path);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 开始迭代
|
||||||
|
int size = candidates.size();
|
||||||
|
for (int i = startIndex; i < size; ++i) {
|
||||||
|
// 剪枝,当现在节点的 sum 已经超过了 target,就没必要继续迭代了
|
||||||
|
if (sum + candidates[i] > target) break;
|
||||||
|
// 剪枝,但保留树枝重复的情况
|
||||||
|
if (i > 0 && candidates[i] == candidates[i - 1] && used[i - 1] == false)
|
||||||
|
continue;
|
||||||
|
path.push_back(candidates[i]);
|
||||||
|
used[i] = true;
|
||||||
|
combinationSum2DFS(candidates, target, i + 1, path, sum + candidates[i],
|
||||||
|
used, result);
|
||||||
|
used[i] = false;
|
||||||
|
path.pop_back();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
## [47. 全排列 II](https://leetcode.cn/problems/permutations-ii/)
|
## [47. 全排列 II](https://leetcode.cn/problems/permutations-ii/)
|
||||||
|
|
||||||
和 s0046 相比就加了去重。有两种去重思路,一个是用哈希表记录每一层的使用情况。另一种是排序 + 判断,后者性能更好所以优先选择后者。
|
和 s0046 相比就加了去重。有两种去重思路,一个是用哈希表记录每一层的使用情况,另一种是排序 + 判断,后者性能更好所以优先选择后者。
|
||||||
|
|
||||||
哈希表法:
|
哈希表法:
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user