Update notes for s0040
This commit is contained in:
parent
ca4fe2293d
commit
fe6a4ec73f
@ -96,4 +96,34 @@ Output:
|
||||
|
||||
正确的逻辑应该是如果 `candidates[i] == candidates[i - 1]` 且 `candidates[i - 1]` 使用过,则剪枝。
|
||||
|
||||
怎么判断 `candidates[i - 1]` 是否使用过呢?我们创建一个 `vector<bool> used` 用来记录每个元素是否使用过。
|
||||
![demo](https://paste.sainnhe.dev/DMfz.png)
|
||||
|
||||
那么我们现在要来定义一下什么叫“使用过”。这张图里面有两种“使用过”,第一种使用过是“在树枝上使用过”,第二种使用过是“在数层上使用过”。
|
||||
|
||||
第一种“使用过”显然是合法的,我们允许元素在一条树枝上重复出现。而第二种“使用过”是不合法的,生成的结果重复了。
|
||||
|
||||
因此我们只需要对第二种“使用过”进行剪枝,而保留第一种“使用过”。
|
||||
|
||||
怎么做呢?我们创建一个 `vector<bool> used` 用来记录元素是否在树枝上出现过,初始化为 `false`。
|
||||
|
||||
```cpp
|
||||
used[i] = true;
|
||||
combinationSum2DFS(candidates, target, i + 1, path, sum + candidates[i],
|
||||
used, result);
|
||||
used[i] = false;
|
||||
```
|
||||
|
||||
那么 `used[i - 1] == true` 说明 `candidates[i - 1]` 在树枝上出现过,我们需要保留这种情况,不剪枝。
|
||||
|
||||
```cpp
|
||||
// 剪枝,但保留树枝重复的情况
|
||||
if (i > 0 && candidates[i] == candidates[i - 1] && used[i - 1] == false)
|
||||
continue;
|
||||
```
|
||||
|
||||
另外需要注意一点,为了进行剪枝,我们需要对 `candidates` 进行排序:
|
||||
|
||||
```cpp
|
||||
// 对 candidates 进行升序排序,这是为了进行剪枝
|
||||
sort(candidates.begin(), candidates.end());
|
||||
```
|
||||
|
@ -14,7 +14,7 @@ void combinationSum2DFS(vector<int> &candidates, int target, int startIndex,
|
||||
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]);
|
||||
|
Loading…
Reference in New Issue
Block a user