求全排列

参考:

1. STL系列之十 全排列(百度迅雷笔试题)

2. 全排列算法非递归实现和递归实现 (C++)

3. [算法]列车算法

题目要求:

写一个函数, 如 Foo(const char *str), 打印出 str 的全排列, 
如 abc 的全排列: abc, acb, bca, dac, cab, cba

一.全排列的递归实现

为方便起见,用123来示例下。123的全排列有123、132、213、231、312、321这六种。首先考虑123和132如何得出:它们的最高位都固定为1(或者说以1为前缀),后边跟上{2,3}的全排列(至于{2,3}的全排列怎么求,则靠递归来完成);213和231同理:以2为前缀,后边跟上{1,3}的全排列;312和321:以3为前缀,后边跟上{1,2}的全排列。

形式化一点的表述——

E= {e1 , ..., en }表示个元素的集合,我们的目标是生成该集合的所有排列方式。

Ei E中移去元素以后所获得的集合,

perm (X) 表示集合中元素的排列方式,

ei . p e r m(X)表示在perm (X) 中的每个排列方式的前面均加上ei 以后所得到的排列方式。

举例——

如果E= {a, b, c},那么E1= {b, c},perm (E1 ) = ( b cc b),e1.perm (E1) = (a b ca c b)。

对于递归的基本部分,采用= 1。当只有一个元素时,只可能产生一种排列方式,所以perm (E) = ( e),其中中的唯一元素。

> 1时,perm (E) = e1.perm (E1 ) +e2.perm(E2 ) +e3.perm (E3) + ? +en .perm (En )。这种递归定义形式是采用perm (X) 来定义perm (E), 其中每个包含n- 1个元素。至此,一个完整的递归定义所需要的基本部分和递归部分都已完成。

也就是说——

n= 3并且E=(abc)时,按照前面的递归定义可得perm (E) =a.perm ( {bc} ) +b.perm ( {a,c} ) +c.perm ( {ab} )。

同样,按照递归定义有perm ( {bc} ) =b.perm ( {c} ) +c.perm ( {b}),

所以a.perm ( {bc} ) = ab.perm ( {c} ) + ac.perm ( {b}) = a b . c ac.b = (a b ca c b)。

同理可得 b.perm ( {ac}) = ... = (b a cb c a),c.perm ( {ab}) = ... = (c a bc b a)。

所以perm (E) = (a b ca c bb a cb c a,c a bc b a)。

 1 public class Permutation {
 2
 3     // 生成arr[k:m]的所有排列方式
 4     private static void perm(char[] arr, int k, int m) {
 5          if (k == m)    // 得到了一个排列方式
 6              System.out.println(Arrays.toString(arr));
 7          else {
 8              // arr[k:m]有多种排列方式,递归地求出来
 9              for (int i = k; i <= m; i++) {
10                  char t = arr[i];  arr[i] = arr[k]; arr[k] = t;
11                  perm(arr, k+1, m);
12                  t = arr[i];  arr[i] = arr[k]; arr[k] = t;
13              }
14          }
15     }
16
17     private static void perm(char[] arr) {
18         perm(arr, 0, arr.length-1);
19     }
20
21     public static void main(String[] args) {
22         char[] sequence = new String("abcd").toCharArray();
23         perm(sequence);
24     }
25
26 }

总结

找到递归关系,把perm(E)问题转化为n个perm(X)问题,其中每个包含n- 1个元素。

时间: 2024-10-12 04:23:11

求全排列的相关文章

PermutationsUnique,求全排列,去重

问题描述:给定一个数组,数组里面有重复元素,求全排列. 算法分析:和上一道题一样,只不过要去重. 3 import java.util.ArrayList; 4 import java.util.HashSet; 5 import java.util.List; 6 import java.util.Set; 7 8 public class PermutationsUnique { 9 public ArrayList<ArrayList<Integer>> permuteUni

nyoj-366-D的小L(求全排列)

D的小L 时间限制:4000 ms  |  内存限制:65535 KB 难度:2 描述       一天TC的匡匡找ACM的小L玩三国杀,但是这会小L忙着哩,不想和匡匡玩但又怕匡匡生气,这时小L给匡匡出了个题目想难倒匡匡(小L很D吧),有一个数n(0<n<10),写出1到n的全排列,这时匡匡有点囧了,,,聪明的你能帮匡匡解围吗? 输入 第一行输入一个数N(0<N<10),表示有N组测试数据.后面的N行输入多组输入数据,每组输入数据都是一个整数x(0<x<10) 输出 按

求全排列的数学方法(洛谷1088 火星人noip2004普及组第4题)

人类终于登上了火星的土地并且见到了神秘的火星人.人类和火星人都无法理解对方的语言,但是我们的科学家发明了一种用数字交流的方法.这种交流方法是这样的,首先,火星人把一个非常大的数字告诉人类科学家,科学家破解这个数字的含义后,再把一个很小的数字加到这个大数上面,把结果告诉火星人,作为人类的回答. 火星人用一种非常简单的方式来表示数字――掰手指.火星人只有一只手,但这只手上有成千上万的手指,这些手指排成一列,分别编号为1,2,3…….火星人的任意两根手指都能随意交换位置,他们就是通过这方法计数的. 一

ACM 求全排列(字典序、邻位对换、递增进位制数,递减进位制数)

字典序:(联合康托展开就也可以按照中介数求) 邻位对换.递增进位制数,递减进位制数:具体的实现和算法讲解如下: 代码..C++版的实现并不好..因为是挨个向后找的,如果K很大的时候会超时,不过...思路是这样...,第二版C++没有完成...因为不想写了,思路很简单,一次加减K就可以了 python代码直接给出,很完美 1 #include<cstdio> 2 #include<cstring> 3 #include<vector> 4 #include<algo

LeetCode46 回溯算法求全排列,这次是真全排列

本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是LeetCode的26篇文章,我们来实战一下全排列问题. 在之前的文章当中,我们讲过八皇后.回溯法,也提到了全排列,但是毕竟没有真正写过.今天的LeetCode46题正是让我们生成给定元素的全排列. 题意很简单,只有一句话,给定一个没有重复元素的序列,让我们返回这个序列所有的全排列,并且我们不需要考虑这些排列的顺序. 回溯法 我们在之前的文章当中分析过,全排列问题,可以看成是搜索问题,从而近似成八皇后问题.在八皇后问题当中,我们枚

字典序排序-求全排列(元素有重复)

思路:数组a的元素分别是1,2,3,3:字典序排序就是找到下一个比1,2,3,3大的数组序列,即1,3,2,3: 步骤如下:1.首先使用Arrays.sort()对待排序数组进行排序:比如输入3213,排序后变成1233:从数组最后一个元素起(即i = 数组长度),将a[i]和a[i-1]比较,找到第一个a[i-1]<a[i]的i-1; 2,此时,a[i]前面可能还存在比a[i-1]大的元素,从数组末尾开始找到第一个比a[i-1]大的元素x,将x和a[i-1]交换,对Arrays.sort(a,

求全排列(数组有重复元素和数组无重复元素) 回溯 递归

http://www.cnblogs.com/TenosDoIt/p/3662644.html 无重复元素 http://blog.csdn.net/havenoidea/article/details/12838479 有重复元素

DFS求全排列

输入 2 1   2 输出 1    2 2    1 代码如下: #include<iostream> #include<stdio.h> #include<algorithm> #include<string.h> using namespace std; int mp[1000],vis[1000],path[1000],n; void dfs(int cnt,int n) { if(cnt==n) { for(int i=0;i<n;i++)

60. Permutation Sequence(求全排列的第k个排列)

The set [1,2,3,-,n] contains a total of n! unique permutations. By listing and labeling all of the permutations in order,We get the following sequence (ie, for n = 3): "123" "132" "213" "231" "312" "3