46. 全排列
给定一个不含重复数字的数组
nums
,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。示例 1:
输入:nums = [1,2,3] 输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
示例 2:
输入:nums = [0,1] 输出:[[0,1],[1,0]]
示例 3:
输入:nums = [1] 输出:[[1]]
提示:
1 <= nums.length <= 6
-10 <= nums[i] <= 10
nums
中的所有整数 互不相同
定义dfs
递归函数,当前树的所有有效序列填充到 ret 数组。
定义ret
数组存储全排列序列。
定义path
存储根节点到当前节点的路径。
定义check
数组,存储当前节点哪些元素是我们的孩子节点,哪些元素不是我们的孩子节点。
维护dfs
递归函数内部逻辑,第一个位置选择一个孩子节点作为路径,然后将子树的所有有效序列填充到ret
数组中。
递归函数的出口,当path.size()==nums.size(),ret.push_back(path); return;
class Solution {vector<vector<int>> ret;vector<int> path;vector<bool> check;public:vector<vector<int>> permute(vector<int>& nums) {check.resize(7);dfs(nums);return ret;}void dfs(vector<int>& nums) {if (path.size() == nums.size()) {ret.push_back(path);return;}int n = nums.size();for (int i = 0; i < n; i++) {if (!check[i]) {path.push_back(nums[i]);check[i] = true;dfs(nums);path.pop_back();check[i] = false;}}}
};
78. 子集
给你一个整数数组
nums
,数组中的元素 互不相同 。返回该数组所有可能的子集
(幂集)。
解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。
示例 1:
输入:nums = [1,2,3] 输出:[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]
示例 2:
输入:nums = [0] 输出:[[],[0]]
提示:
1 <= nums.length <= 10
-10 <= nums[i] <= 10
nums
中的所有元素 互不相同
第一个位置元素选或者不选,第二个位置元素选或者不选,以此类推。
定义dfs
将数中所有有效节点填充到ret
数组中,i
表示当前节点是否选择i
位置元素。
定义ret
数组存储子集序列。
定义path
存储根节点到当前节点的路径。
维护dfs
递归内部逻辑,对于 i 位置的元素,选或者不选,如果不选,将子树的所有有效序列填充到ret
数组中。
如果选,将子树的所有有效序列填充到ret
数组中。
选与不选的时候,将i++
传入下一个节点,此时在本次的节点中,依旧需要维护 i 的意义,所以dfs
后都需要 i--操作。
如果dfs
不传引用,就不需要主动i--
操作,系统自动维护 i 的意义。
选择之后在当前的节点中,还需要维护path
的意义。
递归的出口,当i==nums.size(),ret.push_back(path); return;
class Solution {
public:vector<vector<int>> ret;vector<int> path; // 根节点到当前节点的路径vector<vector<int>> subsets(vector<int>& nums) {// 定义dfs递归函数填充retint i=0;dfs(nums, i);return ret;}void dfs(vector<int>& nums, int& i) {if (i == nums.size()) {ret.push_back(path);return;}// 不选dfs(nums, ++i);i--;// 选path.push_back(nums[i]);dfs(nums, ++i);i--;path.pop_back();}
};
子集的元素有零个,一个,两个,以此类推。
定义dfs
递归函数,将树中每一个节点都填充到ret
数组中,pos
表示子树节点添加的数字的开始下标。
定义path
存储当前节点的序列。
定义ret
存储子集序列。
递归函数内部逻辑,首先将path
添加到ret
数组中。然后进入下一个节点当中,维护path
,和pos
。
递归出口,在维护完ret
后,如果pos==nums.size()
此时返回return
。
class Solution {
public:vector<vector<int>> ret;vector<int> path; vector<vector<int>> subsets(vector<int>& nums) {// 定义dfs递归函数填充retint pos = 0;dfs(nums, pos);return ret;}void dfs(vector<int>& nums, int pos) {ret.push_back(path);if (pos == nums.size())return;for (int i = pos; i < nums.size(); i++) {path.push_back(nums[i]);dfs(nums, i + 1);path.pop_back();}}
};
结尾
最后,感谢您阅读我的文章,希望这些内容能够对您有所启发和帮助。如果您有任何问题或想要分享您的观点,请随时在评论区留言。
同时,不要忘记订阅我的博客以获取更多有趣的内容。在未来的文章中,我将继续探讨这个话题的不同方面,为您呈现更多深度和见解。
谢谢您的支持,期待与您在下一篇文章中再次相遇!