2024年6月16日1:48,正式开启每日一题~
题目要求:给定正整数n(n≥1),给出1~n的全排列,例如,当n=3时全排列是{{1,2,3},{1,3,2},{2,1,3},{2,3,1},{3,1,2},{3,2,1}};
题解思路:归纳法+迭代法:将问题化小,探索规律。
1. 对于n=1时,1的全排列为{{1}};
2. 对于n=2时,2的全排列为{{1,2},{2,1}};
3. 对于n=3时,3的全排列为{{3,1,2},{1,3,2},{2,1,3}};
……
发现规律了吗?
当n=2时,2的全排列是不是在n=1的全排列基础上在1的左边和右边添加了数字2呢?
当n=3时,3的全排列是不是在n=2的全排列基础上在数字1和2的左中右添加数字3呢?
代码思路:
1. 将1作为结果的起点,直接初始化为{{1}},如果n=1则直接输出即可,否则进入循环体;
2. 根据上面的思路,每次更新都需要取上一次的结果,并且对于结果中的每一个值都需要遍历,比如n=2时,我们需要依次取出{1,2}和{2,1}分别做插入3的操作;
注意:利用insert插入会改变原始值,需要利用中间变量保存。
请根据这个思路利用代码实现一下吧!
方法一:非递归方式
vector<vector<int>> getFullPermutation(int n){
if(n < 1){
return {{}};
}
vector<vector<int>> res = {{1}};
if(n == 1){
return res;
}
for(int i = 2; i <= n; i++){
vector<vector<int>> tmp;//每次循环初始化tmp用来保存当前的最终结果
for(auto e:res){
for(int j = 0; j <= e.size(); j++){
vector<int> tmp1 = e;//这里是用来避免insert改变原始值,导致下次插入结果不正确
auto it = tmp1.begin() + j;
tmp1.insert(it, i);
tmp.push_back(tmp1);
}
}
res = tmp;
}
return res;
}
方式二:递归方式
vector<vector<int>> getFullPermutation(vector<vector<int>> res, int n){
if(n < 1){
return {{}};
}
if(n == 1){
return {{1}};
}
res = getFullPermutation(res, n-1);
vector<vector<int>> tmp;//用来记录结果
for(auto e:res){
for(int j = 0; j <= e.size(); j++){
vector<int> tmp1 = e;
auto it = tmp1.begin() + j;
tmp1.insert(it, n);
tmp.push_back(tmp1);
}
}
return tmp;
}
注意:千万不要将tmp初始化为{{}},这并不是说明tmp中没有元素,它有!!!tmp的元素是vector容器,只是这个容器为空而已!
本人已踩坑,找了好久都没有找出毛病,输出总是多一串,错误结果如下:
正确结果:
我这一生,要么光鲜亮丽,要么平庸至极! ——WXL
记录大学学习生活~