【递归进阶练习】全排列

简介: 【递归进阶练习】全排列

题目描述:

排列与组合是常用的数学方法。

先给一个正整数 ( 1 < = n < = 10 )

例如n=3,所有组合,并且按字典序输出:
1 2 3

1 3 2

2 1 3

2 3 1

3 1 2

3 2 1
本文将从以下三种方法介绍本题

1.首先,类似于合法括号,本题可以先选定一个数,对于下一个数,选择放在当前数的左边,右边或中间,生成的下一个集合继续进行下一次迭代,直到遍历完所有情况。

2.考虑到第一种方法需要进行频繁的字符串操作,所以第二种方法是先选定一个字符当前缀,然后逐步增加前缀的长度。如果前缀长度等于输入的长度,就得到了一组解需要注意的是本方法用到递归,需要处理好平行状态。(这种方法的好处还有不需要那麽多空间来记录)

3.进一步考虑,类似于DFS,本题还可以用递归+回溯

逐步生成法:

#include<iostream>
#include<list>
#include<string>
#include<algorithm>
using namespace std;
list<string> getPermutation(string A){
  list<string> res;
  string st(1,A.at(0));
  res.push_back(st);
  int len = A.length();
  for(int i = 1; i < len; i++){
    list<string> res_new;
    char c = A.at(i);
    for(list<string>::iterator it = res.begin(); it != res.end(); it++){
      string str = *it;
      string s_new = *it+c;// 加在后面 
      res_new.push_back(s_new);
      s_new = c+*it;//加在前面 
      res_new.push_back(s_new);
      // 加在中间 
      for(int j = 1; j < str.length(); j++){
        s_new = str.substr(0,j) + c + str.substr(j);
        res_new.push_back(s_new);
      }
    }   
    res = res_new;
  } 
  return res;
}
int main(){
  string s;
  cin >> s;
  list<string> res = getPermutation(s);
  for(list<string>::iterator it = res.begin(); it != res.end(); it++){
    cout << *it << " ";
  }
  cout << endl;
  return 0;
} 

前缀法:

#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
int k, sum = 0;
void getPermutation(string perfix, string arr){
  if(perfix.length() == arr.length()){
    sum++;
    if(sum == k){
      cout << perfix << endl;
      exit(1);
    }
  }
  for(int i = 0; i < arr.length(); i++){
    char c = arr[i];
    if(count(perfix.begin(),perfix.end(),c)  < count(arr.begin(),arr.end(),c))
      getPermutation(perfix+c,arr);
  }
}
int main(){
  string s;
  cin >> s >> k;
  getPermutation("", s);
  return 0;
}

回溯法

#include<iostream>
#include<string>
#include<list>
#include<algorithm>
using namespace std;
list<string> res;
void getPermutationCore(string arr, int k){
  if(k == arr.length()){
    res.push_back(arr);
  }
  for(int i = k; i < arr.length(); i++){
    swap(arr[k], arr[i]); // 把k后面的每个字符放到k的位置上 
    getPermutationCore(arr, k+1); // 放好之后再放下一个元素 
    swap(arr[k], arr[i]); // 回溯 
  }
}
int main(){
  string s;
  cin >> s; 
  getPermutationCore(s,0);
  res.sort();
  for(list<string>::iterator it = res.begin(); it != res.end(); it++)
    cout << *it << " ";
  cout << endl;
  return 0;
}
相关文章
|
2月前
|
人工智能 算法
[第一章]递归与递推
[第一章]递归与递推
40 0
|
21天前
|
存储 算法 数据可视化
力扣156题最全解法:如何上下翻转二叉树(递归与迭代方法详解,附图解)
力扣156题最全解法:如何上下翻转二叉树(递归与迭代方法详解,附图解)
|
22天前
|
存储 机器学习/深度学习 算法
python 3种算法 回溯法、字典序生成、递归交换 实现全排列【力扣46题】
python 3种算法 回溯法、字典序生成、递归交换 实现全排列【力扣46题】
|
12月前
|
机器学习/深度学习
青蛙跳台阶(递归)
青蛙跳台阶(递归)
72 0
|
12月前
|
算法
力扣704二分查找:思路分析+代码实现(递归与非递归)
力扣704二分查找:思路分析+代码实现(递归与非递归)
90 0
|
算法
回溯算法 全排列模板
回溯算法 全排列模板
57 0
【递归】青蛙跳台阶的变式题你还会吗?
【递归】青蛙跳台阶的变式题你还会吗?
98 0
【递归】青蛙跳台阶的变式题你还会吗?
|
机器学习/深度学习 算法 C++
(C/C++)STL函数(3)二分算法题以及二分模板 和(蓝桥杯)递推与递归题目及解法(ACwing)
(C/C++)STL函数(3)二分算法题以及二分模板 和(蓝桥杯)递推与递归题目及解法(ACwing)
(C/C++)STL函数(3)二分算法题以及二分模板 和(蓝桥杯)递推与递归题目及解法(ACwing)
|
机器学习/深度学习 算法
数据结构与算法—递归算法(从阶乘、斐波那契到汉诺塔的递归图解)
递归:就是函数自己调用自己。 子问题须与原始问题为同样的事,或者更为简单; 递归通常可以简单的处理子问题,但是不一定是最好的。
117 0
数据结构与算法—递归算法(从阶乘、斐波那契到汉诺塔的递归图解)