- 乱序全排列 简单回溯算法
- 力扣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解释①#include using namespace std; void backk(vector >& res,vector & 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 nums; vector > 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; }
加入数据的时候使用 push_back()需要先构造临时对象,再将这个对象拷贝到容器的末尾,而emplace_back()则直接在容器的末尾构造对象,这样就省去了拷贝的过程。
尾言
感谢您的阅读!
如果文章有错误请留言指出,谢谢!


![乱序全排列 简单回溯算法详解 [C++] 乱序全排列 简单回溯算法详解 [C++]](http://www.mshxw.com/aiimages/31/876377.png)
