乱序全排列 简单回溯算法详解 [C++]

7 篇文章 0 订阅

乱序全排列 简单回溯算法

力扣46 例题

给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列

例:

输入:[1,3,4]

返回:[[1,3,4],[1,4,3],[3,1,4],[3,4,1],[4,1,3],[4,3,1]]

题解

了解了基本的全排列问题以后(见顺序全排列),了解了基本的回溯算法的思路,那么这道题有了一种新的回溯的思路;

同样的是三个数字,给定了一个数组nums[],但是数组里面的数字并不按照顺序排列,而是任意的三个数字;

基本思路不变,但是我们这次用一个新的思路;

例如[1,2,3],绑定第一个数字1之后,我们只需要交换nums[1]nums[2]的顺序,就可以得到一个新的数列,也就是[1,3,2],同样的思路,绑定了2以后,因为2是nums[1],所以我们只需要交换nums[0]nums[2]的顺序,就可以的到一个新的序列[2,1,3][2,3,1],交换顺序就等价于之前讲过的使用数据,交换回来就相当于重置数据;

那么根据上面的思路,就可以写出代码:

#include <iostream>
#include <vector>
using namespace std;
void backk(vector<vector<int> >& res,vector<int>& output,int first,int len){
    if(first == len){    // 出口 如果已经交换到最后一个了 就可以输出
        res.push_back(output);  // output加入到res容器中
        return ;
    }
    for(int i = first;i < len;i++){      
        swap(output[i],output[first]);  // 绑定第一个数字之后,进入循环开始交换另外两个数
        backk(res,output,first + 1,len);  // 进入递归
        swap(output[i],output[first]);  // 交换完成后,再次交换以重置数据,也就是回溯中的退回
    }
}

int main(){
    vector<int> nums;
    vector<vector<int> > res;
    int n;
    int num;
    cin >> n;
    for(int i = 0;i < n;i++){  // 依次输入准备全排列的数字
        cin >> num;
        nums.push_back(num);       
    }
    backk(res,nums,0,(int)nums.size());
    for(int i = 0;i < res.size();i++){    // 输出二维容器
        for(int j = 0;j< res[i].size();j++){
            cout << res[i][j] << " ";
        }
        cout << endl;
    }
    return 0;
}

/*力扣返回值
vector<vector<int>> permute(vector<int>& nums) {
	vector<vector<int> > res;
	backk(res,nums,0,(int)nums.size());
	return res;
}
*/

解释①

加入数据的时候使用 push_back()需要先构造临时对象,再将这个对象拷贝到容器的末尾,而emplace_back()则直接在容器的末尾构造对象,这样就省去了拷贝的过程。


尾言

感谢您的阅读!
如果文章有错误请留言指出,谢谢!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

linlin9.

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

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

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

打赏作者

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

抵扣说明:

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

余额充值