LeetCode60 n个数的排列组合找出第k个排列
2017-12-06 15:38
453 查看
觉得这道题有必要,我二次回顾,数学。。。。
The set
unique permutations.
By listing and labeling all of the permutations in order,
We get the following sequence (ie, for n = 3):
Given n and k, return the kth permutation sequence.
Note: Given n will be between 1 and 9 inclusive.
第一种解决办法,数学方法解决
第二种方法,我的坑呀,每次都是先想到递归
首先只要两个元素换一下位置,就会使得count++的,假如我取得是1,那么剩下的【2、3、4、5】,再次进行重复的操作,还有的就是递归很容易超时,如何根据k值来减少重复,是很必要的,这个还可以优化,比如说不是用set,而是用上面的boolean[] used 下坐标和数值的位置关系。
我想过用set的迭代器遍历所有值,但是不可以,我觉得应该和我这个迭代冲突了,我也不知道为啥,一上午终于解决这个问题了。
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"
"321"
Given n and k, return the kth permutation sequence.
Note: Given n will be between 1 and 9 inclusive.
第一种解决办法,数学方法解决
//相当于因式分解 public String getPermutation(int n, int k) { int[] factorial = new int ; //因式分解需要的基数 for (int i = 0; i < n; i++) { if (i == 0) { factorial[i] = 1; continue; } factorial[i] = factorial[i - 1] * (i); } //1,1,2,6,24 //1*0+1*1+2*2+6*3+24*4=119 //而我们实际需要的数是:1、2、3、4、5,但他们的组合序列就相当于0、1、2、3、4的组合,只是各自加1而已。 //二者的不同还在于,0-4的k的表是范围是从0-119,而我们的k是从1-120,所以变换关系是k-1。 StringBuilder res = new StringBuilder(); boolean[] used = new boolean ; int i = n - 1; while (i >= 0) { int digit = (k - 1) / factorial[i];//变换关系k-1 res.append(findKth(used, digit));//先取最高位的值 k -= digit * factorial[i--]; } return res.toString(); } //再次强调下,数组是用的地址,而我们传递的对象就是普通的参数 public int findKth(boolean[] used, int digit) { int res = -1; while (digit >= 0) { if (!used[++res]) { //从小到大的去取值,同时进行标记 digit--; } } used[res] = true; return res + 1;//从0-4,变为1-5 }
第二种方法,我的坑呀,每次都是先想到递归
首先只要两个元素换一下位置,就会使得count++的,假如我取得是1,那么剩下的【2、3、4、5】,再次进行重复的操作,还有的就是递归很容易超时,如何根据k值来减少重复,是很必要的,这个还可以优化,比如说不是用set,而是用上面的boolean[] used 下坐标和数值的位置关系。
public String getPermutation(int n, int k) { String str = ""; TreeSet<Integer> set = new TreeSet<>(); for (int i = 1; i <= n; i++) { str += i; set.add(i); } if (k == 1 || n==1) { //System.out.println(k +": "+ str); return str; } str = ""; return getShort(set,k,str); } public int count; public String getShort(TreeSet<Integer> set,int k,String str){ if(set.size()==2){ //System.out.println(str + set.first()+ set.last()); count ++; if(count == k){ return str + set.first()+ set.last(); } //System.out.println(str + set.last()+ set.first()); count ++; if(count == k){ return str + set.last()+ set.first(); } return null; }else{ Object[] array = set.toArray(); for(int i=0;i<array.length;i++){ Integer t = (Integer)array[i]; set.remove(t); str=str+t; int z = count; String ret = getShort(set,k,str); if(count == k){ return ret; } set.add(t); str=str.substring(0, str.length()-1); if(k>(z+((array.length)*(count-z)))){ count =z+array.length * (count-z); i=array.length-1; } } return null; } }
我想过用set的迭代器遍历所有值,但是不可以,我觉得应该和我这个迭代冲突了,我也不知道为啥,一上午终于解决这个问题了。
相关文章推荐
- 【leetcode 排列组合问题】Next Permutation | Permutations | Permutations II | Permutation Sequence
- 数据结构与算法[LeetCode]—找出N个节点的BST的所有形态组合
- LeetCode 全排列、子集、组合总数
- 给定一个字符串,找出其所有不重复的排列组合
- 【题解】【排列组合】【素数】【Leetcode】Unique Paths
- leetcode之深搜递归回溯类之排列与组合类-----77/39/40/216/317 组合 78/90/368 子排列 22/79/93/131 典型递归回溯 46/47 全排列
- 【题解】【排列组合】【回溯】【Leetcode】Generate Parentheses
- Leetcode中的组合排列问题:Permutations,Combinations,Letter Combinations of a Phone Number
- [leetcode 46] Permutations------数组中元素的所有排列组合集合
- leetcode-31 Next Permutation 数字排列组合找到下一个更大值
- leetcode:Permutation Sequence (顺序排列第k个序列) 【面试算法题】
- 寻最优数字筛选算法--找出 “排列数列“ 对应的 “组合数列“
- leetcode | Permutations | 利用深度优先(DFS)的方法排列组合列表
- LeetCode Permutation Sequence(求排列中的第k个排列是什么)
- [LeetCode] k-th permutation 第k个排列
- 每天一道LeetCode-----找到第k个排列
- leetcode-46、47 Permutations/II 数字的排列组合
- LeetCode Median of Two Sorted Arrays 在两个已排列的数组中找出中位数。时间复杂度为O(log(min(N,M))
- LeetCode 笔记21 生成第k个排列
- leetcode 60 第几个排列