目录
状态:去重方法错误。
这道题和之前全排列的区别就在于不是对同一层的重复元素进行去重,而是去除同一父节点下的重复使用元素,为了达到这个目的,需要使用哈希来判断是否重复,注意到数组中值的大小是-100到100之间,因此可以直接利用哈希数组进行判断
- class Solution {
- public:
- vector
int>> res; - vector<int> path;
- void backtracking(vector<int>& nums, int startIndex){
- if(path.size() >= 2){
- res.emplace_back(path);
- }
- int len = nums.size();
- int used[201] = {0};
- for(int i = startIndex; i < len; ++i){
- if((!path.empty() && path.back() > nums[i])
- || used[nums[i] + 100] == 1){
- continue;
- }
- used[nums[i] + 100] = 1;
- path.emplace_back(nums[i]);
- backtracking(nums, i+1);
- path.pop_back();
- }
- }
- vector
int>> findSubsequences(vector<int>& nums) { - res.clear();
- path.clear();
- backtracking(nums, 0);
- return res;
- }
- };
状态:查看思路后AC。
注意全排列和组合(子集)的最大区别在于,全排列的回溯展开每次都是从0开始而不是startIndex,因此需要一个used数组来对已经使用过的节点进行记录,值得注意的是在pop之后,used数组也要进行更新
- class Solution {
- public:
- vector
int>> res; - vector<int> path;
- void backtracking(vector<int>& nums, vector<bool>& used){
- if(path.size() == nums.size()){
- res.emplace_back(path);
- return;
- }
- for(int i = 0; i < nums.size(); ++i){
- if(used[i]) continue;
- used[i] = true;
- path.emplace_back(nums[i]);
- backtracking(nums, used);
- path.pop_back();
- used[i] = false;
- }
- }
- vector
int>> permute(vector<int>& nums) { - res.clear();
- path.clear();
- vector<bool> used(nums.size(), false);
- backtracking(nums, used);
- return res;
- }
- };
状态:查看思路后也没AC。
这里的去重逻辑和组合中的树层去重逻辑类似,注意细节。
- class Solution {
- public:
- vector
int>> res; - vector<int> path;
- void backtracking(vector<int>& nums, vector<bool>& used){
- if(path.size() == nums.size()){
- res.emplace_back(path);
- return;
- }
- for(int i = 0; i < nums.size(); ++i){
- if(i > 0 && nums[i-1] == nums[i] && used[i-1] == true) continue;
- if(used[i] == false){
- used[i] = true;
- path.emplace_back(nums[i]);
- backtracking(nums, used);