递归——全排列(C++)

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容器,只是这个容器为空而已!

 本人已踩坑,找了好久都没有找出毛病,输出总是多一串,错误结果如下:

638b6b6c90d94c228bcffdf661c4df6b.png

正确结果:

d141604422bd4b4ea4288066261b4ea6.png


我这一生,要么光鲜亮丽,要么平庸至极!                             ——WXL

记录大学学习生活~ 

 

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

施霁

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值