提示
1 <= nums.length <= 6
-
-10 <= nums[i] <= 10
-
nums 中的所有整数 互不相同
首先我们要明白排列的概念以及和组合的区别
所谓排列,就是指从给定个数的元素中取出指定个数的元素进行排序。组合则是指从给定个数的元素中仅仅取出指定个数的元素,不考虑排序。
这里我画了一下示例1的图示,如果对排列有不理解的可以看这张图理解
可以看到在每一层递归中我们都会选择一个数字,当选择的数字到达3个后我们把当前的排列加入答案中,然后通过逐级回溯到上层递归去寻找其他的排列,下面我们看代码
首先在主函数中我们要定义一个bool类型的容器,这个容器的作用是用于在递归的时候去跳过当前我们已经在之前选中的数字,结合上面的图我们可以看到:
在第一层中我们选中了1,下一层中就只有2,3可以选择了
同样,如果第一层选中的是2,下一层中就只有1,3可以选择了
如果第一层选中的是3,下一层中就只有1,2可以选择了
因此我们想要知道在当前递归之前我们已经选中了哪些数字,就需要定义一个bool类型的数组或容器,用来标识数组中哪些数字已经被使用了,而这个bool类型的数组或容器大小与题目所给的nums数组是一致的
class Solution {
public:
vector<vector> ans;
vector temp;
int n;
vector<vector> permute(vector& nums) {
n = nums.size();
vector record(n, false);
dfs(0, nums, record);
return ans;
}
};
然后进入dfs函数,出口条件就是递归深度等于了数组长度的时候,同时也是选中了所有的数字的时候,把当前的排列加入答案中,然后回溯到上一层
void dfs(int u, vector& nums, vector& record) {
if(u == n) {
ans.push_back(temp);
return;
}
}
然后要注意在每一层中,我们都遍历数组nums,在循环中判断如果当前nums[i]在record数组中还没有使用过,也就是!record[i]为真时,则把当前nums[i]加入排列中
然后就是一个回溯的写法,进入下一层之间把record[i]置成true表示在下一层递归中当前数字已经使用了,在下一层递归结束后把record[i]又置成false,回溯到进入下一层递归前的状态
void dfs(int u, vector& nums, vector& record) {
if(u == n) {
ans.push_back(temp);
return;
}
for(int i = 0; i < n; i++) {
if(!record[i]) {
record[i] = true;
temp.push_back(nums[i]);
dfs(u + 1, nums, record);
temp.pop_back();
record[i] = false;
}
}
}
然后把代码整合起来
完整代码:
class Solution {
public:
vector<vector> ans;
vector temp;
int n;
void dfs(int u, vector& nums, vector& record) {
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:前端)
最后
正值金三银四招聘旺季,很多小伙伴都询问我有没有前端方面的面试题,特地整理出来赠送给大家!
以扫码获取!!(备注:前端)**
最后
正值金三银四招聘旺季,很多小伙伴都询问我有没有前端方面的面试题,特地整理出来赠送给大家!