全排列问题解析

  文章包含全排列问题、包含重复元素的全排列问题、以及它们的递归和非递归实现、还有如何寻找下一个排列。

二、文章内容 1、全排列问题(递归解法)

描述

给定一个数组nums,要求给出所有排列情况。

例子:nums = {1,2,3},返回结果为

[
  [1,2,3],
  [1,3,2],
  [2,1,3],
  [2,3,1],
  [3,1,2],
  [3,2,1]
]

 

思路

对于以上nums = {1,2,3}的例子,我们对全排列的情况做一个分类:

  ①以1开头,后面跟着{2,3}的全排列

  ②以2开头,后面跟着{1,3}的全排列

  ③以3开头,后面跟着{1,2}的全排列

 

而对于{2,3}、{1,3}、{1,2},我们又可以重复使用以上的思路,下面以{2,3}为例分析:

  ①以2开头,后面跟着{3}的全排列

  ②以3开头,后面跟着{2}的全排列

而对于{2}、{3}这些只有一个数的集合,它们的全排列就是它们本身。这也就是递归的终止条件。

 

以上的思路,用代码按如下方式实现:

对于一个有n个元素的数组a,假设其n个元素分别为a[n-1]。

第一步:

将其分成两个部分,第一个元素a[0]和后面其他元素,全排列表示以a[0]为首的所有排列,等于a[0]加上后面部分的全排列

全排列问题解析

第二步:

使用a[0]和后面的a[1]交换,同样,得到了以a[1]为首的所有全排列。

全排列问题解析

第三步:

交换回原来的序列,然后再交换a[0]和a[2]。这样能得到以a[2]为首的所有排列,然后再交换回初始状态

 

全排列问题解析

 

全排列问题解析

 

 

全排列问题解析

 第四步:

按上面的交换--求排列--再交换回来的流程分别求出以a[3]-a[n-1]为首的所有排列。

这样就得到了所有的排列情况。

 

 注意:对后面部分的排列情况调用递归实现,返回条件是当后面部分只有一个元素的时候。

 

实现:

void get_permute(vector<int>& nums, int pos, vector<vector<int>>& result) { if (nums.size() == pos) { result.push_back(nums); return; } for (int i = pos; i < nums.size(); i++) { swap(nums[pos], nums[i]); get_permute(nums,pos+1,result); swap(nums[i], nums[pos]); } }
vector
<vector<int>> permute(vector<int>& nums) { vector<vector<int>> result; get_permute(nums,0,result); return result; } //这是测试用例 int main() { vector<int> v = {1,1,3}; auto result = permute(v); for (auto i : result) { for (auto j : i) cout << j; cout << endl; } system("pause"); return 0; }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpszxz.html