Skip to content

Commit 27ac2f3

Browse files
authored
up 排列
up 排列
1 parent c2ad7c6 commit 27ac2f3

File tree

1 file changed

+78
-0
lines changed

1 file changed

+78
-0
lines changed

algorithms/algo_notes/回溯专题.md

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,11 @@ public:
321321
## 子集II https://leetcode-cn.com/problems/subsets-ii/
322322
思路:回溯+ 去重
323323
324+
- 同一树层上重复取2 就要过滤掉,同一树枝上就可以重复取2
325+
- used[i - 1] == true,说明同一树枝candidates[i - 1]使用过
326+
- used[i - 1] == false,说明同一树层candidates[i - 1]使用过
327+
- 而我们要对同一树层使用过的元素进行跳过
328+
324329
```c++
325330
class Solution {
326331
private:
@@ -350,3 +355,76 @@ public:
350355
}
351356
};
352357
```
358+
359+
## 排列 1 + 2
360+
排列1:https://leetcode-cn.com/problems/permutations/
361+
362+
排列问题,每次都要从头开始搜索,例如元素1在[1,2]中已经使用过了,但是在[2,1]中还要再使用一次1。
363+
used数组,其实就是记录此时path里都有哪些元素使用了,一个排列里一个元素只能使用一次。
364+
365+
```c++
366+
class Solution {
367+
public:
368+
std::vector<vector<int>> ret;
369+
std::vector<int> path;
370+
std::vector<vector<int>> permute(vector<int>& nums) {
371+
ret.clear();
372+
path.clear();
373+
std::vector<bool> used(nums.size(), false);
374+
backtrack(nums, used);
375+
return ret;
376+
}
377+
void backtrack(std::vector<int>& nums, std::vector<bool>& used) {
378+
if (path.size() == nums.size()) {
379+
ret.push_back(path);
380+
return;
381+
}
382+
for (int i = 0; i < nums.size(); ++i) {
383+
if (used[i] == true) continue;//记录此时path里都有哪些元素使用了,一个排列里一个元素只能使用一次。
384+
path.push_back(nums[i]);
385+
used[i] = true;
386+
backtrack(nums, used);
387+
used[i] = false;
388+
path.pop_back();
389+
}
390+
}
391+
};
392+
393+
```
394+
395+
排列2:给定一个可包含重复数字的序列,要返回所有不重复的全排列。
396+
https://leetcode-cn.com/problems/permutations-ii/
397+
398+
```c++
399+
class Solution {
400+
public:
401+
std::vector<vector<int>> ret;
402+
std::vector<int> path;
403+
std::vector<vector<int>> permuteUnique(vector<int>& nums) {
404+
ret.clear();
405+
path.clear();
406+
std::sort(nums.begin(), nums.end());//排序
407+
std::vector<bool> used(nums.size(), false);
408+
backtrack(nums, used);
409+
return ret;
410+
}
411+
void backtrack(std::vector<int>& nums, std::vector<bool>& used) {
412+
if (path.size() == nums.size()) {
413+
ret.push_back(path);
414+
return;
415+
}
416+
for (int i = 0; i < nums.size(); ++i) {
417+
// used[i - 1] == true,说明同一树枝nums[i - 1]使用过
418+
// used[i - 1] == false,说明同一树层nums[i - 1]使用过
419+
// 如果同一树层nums[i - 1]使用过则直接跳过
420+
if (i > 0 && nums[i] == nums[i - 1] && used[i - 1] == false) continue;
421+
if (used[i] == true) continue;//u记录此时path里都有哪些元素使用了,一个排列里一个元素只能使用一次。
422+
path.push_back(nums[i]);
423+
used[i] = true;
424+
backtrack(nums, used);
425+
used[i] = false;
426+
path.pop_back();
427+
}
428+
}
429+
};
430+
```

0 commit comments

Comments
 (0)