【递归进阶练习】全排列

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

题目描述:

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

先给一个正整数 ( 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;
}
相关文章
|
存储 算法
蓝桥杯:递归 与 例题:斐波那契数列及优化与应用
蓝桥杯:递归 与 例题:斐波那契数列及优化与应用
81 0
|
2月前
|
算法 定位技术
数据结构与算法学习九:学习递归。递归的经典实例:打印问题、阶乘问题、递归-迷宫问题、八皇后问题
本文详细介绍了递归的概念、重要规则、形式,并展示了递归在解决打印问题、阶乘问题、迷宫问题和八皇后问题等经典实例中的应用。
48 0
|
6月前
|
存储 机器学习/深度学习 算法
python 3种算法 回溯法、字典序生成、递归交换 实现全排列【力扣46题】
python 3种算法 回溯法、字典序生成、递归交换 实现全排列【力扣46题】
|
7月前
|
Java Python
汉诺塔递归问题,递归思路详解
汉诺塔递归问题,递归思路详解
108 0
|
算法
力扣704二分查找:思路分析+代码实现(递归与非递归)
力扣704二分查找:思路分析+代码实现(递归与非递归)
139 0
|
机器学习/深度学习 算法 C++
(C/C++)STL函数(3)二分算法题以及二分模板 和(蓝桥杯)递推与递归题目及解法(ACwing)
(C/C++)STL函数(3)二分算法题以及二分模板 和(蓝桥杯)递推与递归题目及解法(ACwing)
(C/C++)STL函数(3)二分算法题以及二分模板 和(蓝桥杯)递推与递归题目及解法(ACwing)
(蓝桥杯)递推与递归,前缀和,二分经典例题分析
(蓝桥杯)递推与递归,前缀和,二分经典例题分析
(蓝桥杯)递推与递归,前缀和,二分经典例题分析
看代码求结果练习题(递归例题)
看代码求结果练习题(递归例题)
98 0
看代码求结果练习题(递归例题)