全排列的递归实现

  对于全排列问题,假设我们有n个不同的数字,需要对其进行全排列,那么全排列的总数为f(n),f(n) = n * f(n - 1)。我们可以看做是将第一个数字固定,然后对后边n-1个数字进行全排,这样第一个数字就有n种选择。同理,在求f(n - 1)时,可以看做第二个数字固定,后边n-2个数字进行全排,这样第二个数字就有n-2种选择。具体算法如下:

 1 int swap(int &a, int &b)
 2 {
 3     int tmp = a;
 4     a = b;
 5     b = tmp;
 6 }
 7
 8 void Print(int *a, int len)
 9 {
10     for(int i = 0; i != len; ++i)
11         cout << a[i] << " ";
12     cout << endl;
13 }
14
15 void Permutation(int *a, int start, int len)
16 {
17     if(start == len)              //当到达末尾时输出整个数组
18     {
19         Print(a, len);
20         return;
21     }
22
23     for(int i = start; i != len; ++i)    //第i个数有n-i+1中选择
24     {
25         swap(a[i], a[start]);                   //为了保证每一次第一个数不同,让其与后边的数字依次调换
26         Permutation(a, start + 1, len);
27         swap(a[i], a[start]);                   //进行全排后再次调换回去,防止多次调换同一个数
28     }
29 }
时间: 2024-10-10 23:35:15

全排列的递归实现的相关文章

从全排列看递归

1.什么是递归 1)举个生活中的例子:假设有一项很繁重的工作,我们总能把它划分为:总工作量=今天的工作+剩下的工作,只要我们每天都在坚持,一点点继续,那么剩下的工作会越来越少,总有一天,我们可以实现我们的梦想!(程序员的自我安慰~) 2)数学上来看: 例如:n的阶乘 f(n) = n!,n为整数 f(n) = 1   n<= 1                       (1) n*f(n-1) n >1                  (2) 有一个基础部分:它包含一个或多个值,对这些值

n个整数全排列的递归实现(C++)

全排列是非常常用的一个小算法,下面是n个整数全排列的递归实现,使用的是C++ #include <iostream> using namespace std; int n = 0; void swap(char *a ,char *b) { int m ; m = *a; *a = *b; *b = m; } void perm(char list[],int k, int m ) { int i; if(k >m) { for(i = 0 ; i <= m ; i++) { co

C++ 全排列问题——递归枚举法

全排列问题是一道非常经典的递归题目,而递归枚举法求解也是最暴力的一种方法. 例题 洛谷1706 题目描述 输出自然数1到n所有不重复的排列,即n的全排列,要求所产生的任一数字序列中不允许出现重复的数字. 输入格式 一个整数n. 输出格式 由1-n组成的所有不重复的数字序列,每行一个序列. 每个数字保留 5个场宽. 输入样例 3 输出样例 1 2 3 1 3 2 2 1 3 2 3 1 3 1 2 3 2 1 全排列问题--递归枚举法 这是一道经典的递归的题,每次递归枚举第x个数字是几,就是从1到

C++ 全排列问题——递归交换法

对于求解全排列问题有最暴力的递归枚举法,但是我们希望可以优化时间,因此出现了递归交换法. 例题 洛谷1706 题目描述 输出自然数1到n所有不重复的排列,即n的全排列,要求所产生的任一数字序列中不允许出现重复的数字. 输入格式 一个整数n. 输出格式 由1-n组成的所有不重复的数字序列,每行一个序列. 每个数字保留 5个场宽. 输入样例 3 输出样例 1 2 3 1 3 2 2 1 3 2 3 1 3 1 2 3 2 1 全排列问题--递归交换法 其实跟暴力枚举思路差不多,每次递归枚举第x个数字

全排列 (递归求解+字典序) java 转载

问题:给出一个字符串,输出所有可能的排列. 全排列有多种算法,此处仅介绍常用的两种:字典序法和递归法. 1.字典序法: 如何计算字符串的下一个排列了?来考虑"926520"这个字符串,我们从后向前找第一双相邻的递增数字,"20"."52"都是非递增的,"26 "即满足要求,称前一个数字2为替换数,替换数的下标称为替换点,再从后面找一个比替换数大的最小数(这个数必然存在),0.2都不行,5可以,将5和2交换得到"956

全排列非递归写法

输出n的全排列 #include<iostream> #include<cstdio> using namespace std; #define MAXN 10 int vis[MAXN]; int stack[MAXN]; int n,k,num,top; void dfs(int n) { int st=1; stack[top++]=1; vis[1]=1; st=1; while(top||st<n) { if(top==n) {for(int i=0;i<to

字符串全排列的递归实现

#include "stdafx.h" #include <iostream> #include <assert.h> using namespace std; void permutation(char *pStr, char* pBegin) { assert(pStr&&pBegin); if (*pBegin == '\0') cout << pStr << endl; else { for (char* pCh

[Leetcode 46]全排列 Permutations 递归

[题目] Given a collection of distinct integers, return all possible permutations. 数组的组合情况. Input: [1,2,3] Output: [ [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1] ] [思路] 求子集,排列组合的数组题有固定模板. [代码] class Solution { public List<List<Integer>> p

uva 140 Bandwidth(全排列+递归)

快睡觉的时候1A的把序列全排列,递归暴力判断就ok啦,我改成对应的整数存了,a数组存的是所有的字符的排列, b数组存的是所有开始节点的排列,map[i][j]数组存的是i为起点,与j相邻 贴代码: #include<stdio.h> #include<stdlib.h> #include<string.h> #include<limits.h> #include<math.h> #include<algorithm> using na