Permutation Sequence
2016-05-13 09:08
260 查看
【题目】
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。
第二种:数学解法
在n!个排列中,第一位的元素总是(n-1)!一组出现的,也就说如果p = k / (n-1)!,那么排列的最开始一个元素一定是nums[p]。
别人的:
1. 能否直接算出集合{1, 2, ..., m}的第n个排列?
设某个集合{a1, a2, ..., am}(a1<a2<...<am)构成的某种序列pn,基于以上分析易证得:若as<at,那么将as作为第1个元素的所有序列一定都小于at作为第1个元素的任意序列。同理可证得:第1个元素确定后,剩下的元素中若as'<at',那么将as'作为第2个元素的所有序列一定都小于作为第2个元素的任意序列。例如4个数的集合{2,
3, 4, 6}构成的序列中,以3作为第1个元素的序列一定小于以4或6作为第1个元素的序列;3作为第1个元素的前题下,2作为第2个元素的序列一定小于以4或6作为第2个元素的序列。
推广可知,在确定前i(i<n)个元素后,在剩下的m-i=s个元素的集合{aq1, aq2, ..., aq3}(aq1<aq2<...<aqm)中,以aqj作为第i+1个元素的序列一定小于以aqj+1作为第i+1个元素的序列。由此可知:在确定前i个元素后,一共可生成s!种连续大小的序列。
根据以上分析,对于给定的n(必有n<=m!)可以从第1位开始向右逐位地确定每一位元素。在第1位不变的前题下,后面m-1位一共可以生成(m-1)!中连续大小的序列。若n>(m-1)!,则第1位不会是a1,n中可以容纳x个(m-1)!即代表第1位是ax。在确定第1位后,将第1位从原集合中删除,得到新的集合{aq1, aq2, ..., aq3}(aq1<aq2<...<aqm),然后令n1=n-x(m-1)!,求这m-1个数中生成的第n1个序列的第1位。
举例说明:如7个数的集合为{1, 2, 3, 4, 5, 6, 7},要求出第n=1654个排列。
(1654 / 6!)取整得2,确定第1位为3,剩下的6个数{1, 2, 4, 5, 6, 7},求第1654 % 6!=214个序列;
(214 / 5!)取整得1,确定第2位为2,剩下5个数{1, 4, 5, 6, 7},求第214 % 5!=94个序列;
(94 / 4!)取整得3,确定第3位为6,剩下4个数{1, 4, 5, 7},求第94 % 4!=22个序列;
(22 / 3!)取整得3,确定第4位为7,剩下3个数{1, 4, 5},求第22 % 3!=4个序列;
(4 / 2!)得2,确定第5为5,剩下2个数{1, 4};由于4 % 2!=0,故第6位和第7位为增序<1 4>;
因此所有排列为:3267514。
2:加了额外空间
给定一种排列,如何算出这是第几个排列呢?
和前一个问题的推导过程相反。例如3267514:
后6位的全排列为6!,3为{1, 2, 3 ,4 , 5, 6, 7}中第2个元素(从0开始计数),故2*720=1440;
后5位的全排列为5!,2为{1, 2, 4, 5, 6, 7}中第1个元素,故1*5!=120;
后4位的全排列为4!,6为{1, 4, 5, 6, 7}中第3个元素,故3*4!=72;
后3位的全排列为3!,7为{1, 4, 5, 7}中第3个元素,故3*3!=18;
后2位的全排列为2!,5为{1, 4, 5}中第2个元素,故2*2!=4;
最后2位为增序,因此计数0,求和得:1440+120+72+18+4=1654
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。
public class Solution { public String getPermutation(int n, int k) { // 初始化起始数组 char[] init = new char ; for (int i = 0; i < n; i++) { seq[i] = (char) ('0' + i + 1); } // 利用nextPermutation找到第k个 for (int i = 1; i < k; i++) { nextPermutation(init ); } return String.valueOf(init ); } public void nextPermutation(char[] init) { // find the last adjacent two element that is in ascending order int i = init.length - 1; while (i > 0 && init[i - 1] >= init[i]) { i--; } if (i == 0) return; int j = init.length - 1; while (j >= i && init[i - 1] >= init[j]) { j--; } char tmp = init[i - 1]; init[i - 1] = init[j]; init[j] = tmp; int l = i; int r = init.length - 1; while (l < r) { tmp = init[l]; init[l] = init[r]; init[r] = tmp; l++; r--; } } }
第二种:数学解法
在n!个排列中,第一位的元素总是(n-1)!一组出现的,也就说如果p = k / (n-1)!,那么排列的最开始一个元素一定是nums[p]。
别人的:
1. 能否直接算出集合{1, 2, ..., m}的第n个排列?
设某个集合{a1, a2, ..., am}(a1<a2<...<am)构成的某种序列pn,基于以上分析易证得:若as<at,那么将as作为第1个元素的所有序列一定都小于at作为第1个元素的任意序列。同理可证得:第1个元素确定后,剩下的元素中若as'<at',那么将as'作为第2个元素的所有序列一定都小于作为第2个元素的任意序列。例如4个数的集合{2,
3, 4, 6}构成的序列中,以3作为第1个元素的序列一定小于以4或6作为第1个元素的序列;3作为第1个元素的前题下,2作为第2个元素的序列一定小于以4或6作为第2个元素的序列。
推广可知,在确定前i(i<n)个元素后,在剩下的m-i=s个元素的集合{aq1, aq2, ..., aq3}(aq1<aq2<...<aqm)中,以aqj作为第i+1个元素的序列一定小于以aqj+1作为第i+1个元素的序列。由此可知:在确定前i个元素后,一共可生成s!种连续大小的序列。
根据以上分析,对于给定的n(必有n<=m!)可以从第1位开始向右逐位地确定每一位元素。在第1位不变的前题下,后面m-1位一共可以生成(m-1)!中连续大小的序列。若n>(m-1)!,则第1位不会是a1,n中可以容纳x个(m-1)!即代表第1位是ax。在确定第1位后,将第1位从原集合中删除,得到新的集合{aq1, aq2, ..., aq3}(aq1<aq2<...<aqm),然后令n1=n-x(m-1)!,求这m-1个数中生成的第n1个序列的第1位。
举例说明:如7个数的集合为{1, 2, 3, 4, 5, 6, 7},要求出第n=1654个排列。
(1654 / 6!)取整得2,确定第1位为3,剩下的6个数{1, 2, 4, 5, 6, 7},求第1654 % 6!=214个序列;
(214 / 5!)取整得1,确定第2位为2,剩下5个数{1, 4, 5, 6, 7},求第214 % 5!=94个序列;
(94 / 4!)取整得3,确定第3位为6,剩下4个数{1, 4, 5, 7},求第94 % 4!=22个序列;
(22 / 3!)取整得3,确定第4位为7,剩下3个数{1, 4, 5},求第22 % 3!=4个序列;
(4 / 2!)得2,确定第5为5,剩下2个数{1, 4};由于4 % 2!=0,故第6位和第7位为增序<1 4>;
因此所有排列为:3267514。
1: public String getPermutation(int n, int k) { int []num = new int ; int permCount = 1; for(int i=0;i<n;i++){ num[i] = i+1; permCount*=(i+1); } k--; StringBuilder target = new StringBuilder(); for(int i=0;i<n;i++){ permCount = permCount/(n-i); int choosed = k/permCount; target.append(num[choosed]); for(int j=choosed;j<n-i-1;j++){ num[j] = num[j+1]; } k = k%permCount; } return target.toString(); }
2:加了额外空间
public class Solution { public String getPermutation(int n, int k) { int data[]=new int[10]; boolean visited[]=new boolean[10]; data[0]=data[1]=1; ArrayList<Integer> list=new ArrayList<Integer>(); for(int i=1;i<=n;i++) { data[i]=data[i-1]*(i); list.add(i); } String result=""; k--; for(int i=n-1;i>=0;i--) { int cur=k/data[i]; int j=1; for(;j<9;j++) //从数组中 针对未访问过的元素visited[]=false 找第cur个,找到的为j { if(visited[j]==false) cur--; if(cur<0) break; } visited[j]=true; result+=(j); k=k%data[i]; } return result; } }
给定一种排列,如何算出这是第几个排列呢?
和前一个问题的推导过程相反。例如3267514:
后6位的全排列为6!,3为{1, 2, 3 ,4 , 5, 6, 7}中第2个元素(从0开始计数),故2*720=1440;
后5位的全排列为5!,2为{1, 2, 4, 5, 6, 7}中第1个元素,故1*5!=120;
后4位的全排列为4!,6为{1, 4, 5, 6, 7}中第3个元素,故3*4!=72;
后3位的全排列为3!,7为{1, 4, 5, 7}中第3个元素,故3*3!=18;
后2位的全排列为2!,5为{1, 4, 5}中第2个元素,故2*2!=4;
最后2位为增序,因此计数0,求和得:1440+120+72+18+4=1654
相关文章推荐
- init: sys_prop: permission denied uid:1003 name:service.bootanim.exit
- iOS开发------操作通讯录(AddressBook篇)&通讯录UI(AddressBookUI篇)
- 手势(UIGestureXXX)使用详解
- 定义一个UIEdgeInsets全局变量
- Android Data Binding Guide
- 通过代理监听UITextField按下了return按钮
- 监听UITextField输入一般用addtarget
- UITextField设置了占位文字内容之后,才能设置占位文字的颜色
- UITextField监听按下了删除按钮
- 深入理解Java PriorityQueue
- UIButton的运用
- UILabel的使用
- 常用UI控件
- StringBuilder和StringBuffer源码浅析
- xiaocong的uiautomator有时候找不到界面元素的问题和解决
- mysql unique option prefix myisam_recover instead of myisam-recover-options的解决方法
- 解决easyui-datagrid在IE中无法reload问题
- 自定义UITabBarController及tabBarItem的具体设置
- 华为Quidway交换机DHCP IP地址排除
- SPOJ GSS5 Can you answer these queries V