代码随想录算法训练营第二十八天 491.递增子序列、46.全排列、47.全排列II 491.递增子序列
题目链接:力扣题目链接
文章讲解:代码随想录(https://programmercarl.com)
视频讲解:回溯算法精讲,树层去重与树枝去重 | LeetCode:491.递增子序列
状态:AC
思路 先查找递增子序列,其次要去重。难点还是在于去重。
查找递增时候,每次需要判断当前的nums[i]
是否大于path[-1]
。
去重和之前的还不大一样,因为这里不可以进行排序。应该判断每层的情况
代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 class Solution {private : vector<vector<int >> result; vector<int > path; void backTracking (vector<int > &nums, int index) { if (path.size () > 1 ) { result.push_back (path); } unordered_set<int > sets; for (int i = index; i < nums.size (); ++i) { if ((!path.empty () && path.back () > nums[i]) || sets.find (nums[i]) != sets.end ()) { continue ; } path.push_back (nums[i]); sets.insert (nums[i]); backTracking (nums, i + 1 ); path.pop_back (); } }public : vector<vector<int >> findSubsequences (vector<int > &nums) { backTracking (nums, 0 ); return result; } };
46. 全排列
题目链接:力扣题目链接
文章讲解:代码随想录(https://programmercarl.com)
视频讲解:组合与排列的区别,回溯算法求解的时候,有何不同?| LeetCode:46.全排列
状态:AC
思路 递归三部曲 保存使用过的数,这里保存的实际上是该数的位置。用的二进制来节省空间。例如,使用了第0个数,括号里指的是该数为二进制,used=1(2)
。使用了第0、2个数,那么则是used=101(2)
,使用了第0、1、3、6个数,used=1001011(2)
。即使用了第i个数,used += 1 << i
。判断第i个数是否使用过:1 >> i & used
确立函数和返回值
递归终止条件:path
长度等于 nums
长度
单次递归:如果当前的数没被使用过,加入path
代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 class Solution {private : vector<vector<int >> result; vector<int > path; void backTracking (vector<int > &nums, int used) { if (nums.size () == path.size ()) { result.push_back (path); return ; } for (int i = 0 ; i < nums.size (); ++i) { if (used >> i & 1 ) { continue ; } path.push_back (nums[i]); used += 1 << i; backTracking (nums, used); path.pop_back (); used -= 1 << i; } }public : vector<vector<int >> permute (vector<int > &nums) { int used = 0 ; backTracking (nums, used); return result; } };
47. 全排列II
题目链接:力扣题目链接
文章讲解:代码随想录(https://programmercarl.com)
视频讲解:回溯算法求解全排列,如何去重?| LeetCode:47.全排列 II
状态:AC
思路 力扣40题个人博客跳转 + 上一题。used还是使用数组表示。
代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 class Solution {private : vector<vector<int >> result; vector<int > path; void backTracking (vector<int > &nums, vector<bool > used2) { if (nums.size () == path.size ()) { result.push_back (path); } for (int i = 0 ; i < nums.size (); ++i) { if (i > 0 && nums[i - 1 ] == nums[i] && !used2[i - 1 ]) { continue ; } if (!used2[i]) { used2[i] = true ; path.push_back (nums[i]); backTracking (nums, used2); path.pop_back (); used2[i] = false ; } } }public : vector<vector<int >> permuteUnique (vector<int > &nums) { sort (nums.begin (), nums.end ()); vector<bool > used2 (nums.size(), false ) ; backTracking (nums, used2); return result; } };