[LeetCode] Permutations 排列生成算法之字典序法

字典序排序生成算法

字典序法就是按照字典排序的思想逐一产生所有排列。

例如,由1,2,3,4组成的所有排列,从小到大的依次为:

1234, 1243, 1324, 1342, 1423, 1432,

2134, 2143, 2314, 2341, 2413, 2431,

3124, 3142, 3214, 3241, 3412, 3421,

4123, 4132, 4213, 4231, 4312, 4321.

分析这种过程,看后一个排列与前一个排列之间有什么关系?

再如,设有排列(p)=2763541,按照字典式排序,它的下一个排列是什么?

  1. 2763541
    (找最后一个正序35)
  2. 2763541
    (找3后面比3大的最后一个数4)
  3. 2764531
    (交换3,4的位置)
  4. 2764135 (把4后面的5,3,1反转)

下面给出求 p[1…n] 的下一个排列的描述:

  1. 求 i = max{j | p[j – 1] < p[j]} (找最后一个正序)
  2. 求 j = max{k| p[i – 1] < p[k]} (找最后大于 p[i – 1] 的)
  3. 交换 p[i – 1] 与 p[j]得到 p[1] … p[i-2] p[j] p[i] p[i+1] … p[j-1] p[i-1] p[j+1]
    … p[n]
  4. 反转 p[j] 后面的数得到 p[1] … p[i-2] p[j] p[n] … p[j+1] p[i-1] p[j-1] … p[i]

Next Permutation

Description:

  • Implement next permutation, which rearranges numbers into the lexicographically next greater permutation of numbers.
  • If such arrangement is not possible, it must rearrange it as the lowest possible order (ie, sorted in ascending order).
  • The replacement must be in-place, do not allocate extra memory.

Here are some examples. Inputs are in the left-hand column and its corresponding outputs are in the right-hand column.

1,2,3 → 1,3,2

3,2,1 → 1,2,3

1,1,5 → 1,5,1

题意:实现一个求下一个排列的方法。要求:1) 下一个排列要在字典序上大于当前排列;2) 如果没有比当前序列更大的排列,那么下一个为最小的排列;3) 需要在原地操作,即不用额外的空间。

分析:按照上面的方法直接实现即可。需要注意与上面方法不同的是,下面的实现是循环的,即字典序的最后一个排列[4,3,2,1]的后面是[1,2,3,4]。

Permutations

Description: Given a collection of numbers, return all possible permutations. For example, [1,2,3]
have the following permutations: [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], and [3,2,1].

题意:求集合中所有数的全排列。

分析:我们知道n个数的全排列有n!个,那么根据 Next
Permutation 一个一个求出即可。

Permutations II

Description: Given a collection of numbers that might contain duplicates, return all possible unique
permutations. For example, [1,1,2] have the following unique permutations: [1,1,2], [1,2,1], and [2,1,1].

题意:求集合中所有数的全排列,注意集合中可能存在重复的数。

分析:方法与 Permutations 相同,只是有了重复数后,全排列的总数就不足n!个了,我们的方法是先对所有数排序,即从最小的排列开始找,找到最后一个排列时结束。

Permutation Sequence

Description: 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):

1. “123”

2. “132”

3. “213”

4. “231”

5. “312”

6. “321”

Given n and k, return the kth permutation sequence. Note: Given n will be between 1 and 9 inclusive.

题意:按照字典序法,求n个数的全排列中第k个排列,注意返回排列的形式为字符串。

分析:从最小的排列开始,根据 Next
Permutation 找到第k个排列即可。

(完)

转载请注明:来自梁佳宾的网络日志

时间: 2024-08-06 07:41:27

[LeetCode] Permutations 排列生成算法之字典序法的相关文章

Leetcode:Permutations 排列

戳我去解题 Given a collection of numbers, return all possible permutations. For example,[1,2,3] have the following permutations:[1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], and [3,2,1]. 解题分析:首先进行排序,保证结果保持字典序 class Solution { public: vector<vector<int>

排列生成算法--C++

1 #include<iostream> 2 using namespace std; 3 //初始化,注意两边的初始化,简化算法 4 void Init(int n , int *arr , bool * flags) 5 { 6 arr[0] = 0xfffffff; 7 for(int i = 1;i <= n;i++) 8 { 9 arr[i] = i; 10 flags[i] = false; 11 } 12 arr[n+1] = 0xfffffff; 13 } 14 //检查

暴力搜索专题小结:全排列及可重集排列生成算法

1~n的全排列 (1)思路:按照递归的思想,初始化集合S中含有1~n所有元素.如果1~n的集合S为空,那么输出全排列:否则从小到大依次考虑每个元素i,在A的末尾添加i后,集合S变为S-{i}.这里我们不需要集合S,只需要利用一个变量cur表示当前位要填的数即可.那么A中没有出现过的元素均可以选择. #define N 100 int A[N]; void print_permutation(int n, int*A, int cur) { if (cur == n) { for (int i =

PHP_字典序法获得排列组合

前段时间一次聚会闲聊时聊到一个问题,就是给你一排数组,例如1,2,3,4,5,如何能高效的获取上述数列的所有排列组合,正巧没事,研究了一下,一开始以为是个很简单的问题,就直接开始写代码了,后来发现怎么循环也不理想,基本上都有一些不必要的消耗,百度一下看到一个不错的算法,字典序法,顺便学习一下,然后记录之. 摘一段算法思想: 设P是[1,n]的一个全排列. P=P1P2-Pn=P1P2-Pj-1PjPj+1-Pk-1PkPk+1-Pn , j=max{i|Pi<Pi+1}, k=max{i|Pi>

全排列的生成算法

[复制转载] //全排列的生成算法 // 全排列的生成算法就是对于给定的字符集,用有效的方法将所有可能的全排列无重复无遗漏地枚举出来.任何n个字符集的排列都可以与1-n的n个数字的排列一一对应, // 因此在此就以n个数字的排列为例说明排列的生成法. // n个字符的全体排列之间存在一个确定的线性顺序关系.所有的排列中除最后一个排列外,都有一个后继:除第一个排列外,都有一个前驱.每个排列的后继都可以从 // 它的前驱经过最少的变化而得到,全排列的生成算法就是从第一个排列开始逐个生成所有的排列的方

字典序法生成全排列算法的证明

引言 对一个给定数据进行全排列,在各种场合经常会用到.组合数学中,生成全排列的方法有很多,卢开澄老师的<组合数学>中就介绍了三种:序数法,字典序法,临位互换法等.其中以字典序法由于算法简单,并且使用的时候可以依照当前状态获取下一个状态,直到所有排列全部完成,方便在程序中随要随用,应用比较广泛,STL中的Next_permutation也是使用此法. 算法定义 首先看什么叫字典序,顾名思义就是按照字典的顺序(a-z, 1-9).以字典序为基础,我们可以得出任意两个数字串的大小.比如 "

字典序法生成全排列算法图

算法定义 首先看什么叫字典序,顾名思义就是按照字典的顺序(a-z, 1-9).以字典序为基础,我们可以得出任意两个数字串的大小.比如 "1" < "12"<"13". 就是按每个数字位逐个比较的结果.对于一个数字串,"123456789", 可以知道最小的串是 从小到大的有序串"123456789",而最大的串是从大到小的有序串"*987654321".这样对于"1

排列的生成算法

字典序法 对于按字典的顺序给出的排列(p=p(1)p(2)p(3)p(4)…p(n)),由一个排列生成下一个排列的算法如下: (1)求满足关系式p(j-1)<p(j)的j的最大值设为i,即 i=max{j|p(j-1)<p(j)} (2)求满足关系式p(i-1)<p(k)的k的最大值设为j,即 j=max{k|p(i-1)<p(k)} (3)p(i-1)与p(j)互换位置,得到p'=p(1)p(2)…p(n) (4)在p'=p(1)p(2)…p(i-1)p(i)p(i+1)…p(n

基于字典序的组合生成算法

基于字典序的组合生成算法 2010-12-02 01:22:52|  分类: 离散数学 |  标签:离散数学  排列组合   |举报 |字号大中小 订阅 一. 问题描述 给定非空集合A,按字典序的方法生成集合A的所有组合.关于字典序的概念,这里不做严格定义,只是做一简单解释. 字典序是字符串比较的一种方法.例如两个字符串 abcd,abef,这两个字符串谁大? 显然,abef>abcd:如何得出这个结论的呢? 从左至右依次比较每一个字符,首先比较两个串的第一个字符,都是a,相等:其次比较两个串的