码迷,mamicode.com
首页 > 其他好文 > 详细

Leetcode: Permutation Sequence

时间:2014-10-12 10:10:07      阅读:217      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   io   os   ar   for   sp   

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.

看到这道题,第一时间就联系到了Next Permutation. 那道题是让找下一个稍大的Permutation, 而这里是找从小到大第K大的Permutation, 而最小的Permutation我们明显知道,那么用Next Permutation做Subroutine,做K次,不就找到了所需的Permutation了吗。Next Permutation时间复杂度为O(N), 这里就是O(N*k).

代码里面把Int数组拷贝成一个char数组,是为了方便转换成String

 1 public class Solution {
 2     public String getPermutation(int n, int k) {
 3         if (n < 0) return"";
 4         int[] num = new int[n];
 5         char[] numcopy = new char[n];
 6         for (int z=0; z<n; z++) {
 7             num[z] = z + 1;
 8         }
 9         for (int i=2; i<=k; i++) {
10             nextPermutation(num);
11         }
12         for (int z=0; z<n; z++) {
13             numcopy[z] = (char)(‘0‘ + num[z]);
14         }
15         return new String(numcopy);
16     }
17     
18     public void nextPermutation(int[] num) {
19         if (num == null || num.length == 0 || num.length == 1) return;
20         int i = num.length-2;
21         while (i>=0 && num[i]>=num[i+1]) {
22             i--;
23         }
24         if (i >= 0) {
25             int j = i;
26             while (j<num.length-1 && num[j+1]>num[i]) {
27                 j++;
28             }
29             int temp = num[i];
30             num[i] = num[j];
31             num[j] = temp;
32         }
33         reverse(num, i+1);
34     }
35     
36     public void reverse(int[] num, int k) {
37         int start = k;
38         int end = num.length - 1;
39         while (start < end) {
40             int temp = num[start];
41             num[start] = num[end];
42             num[end] = temp;
43             start++;
44             end--;
45         }
46     }
47 }

我这个方法很直接,但是时间复杂度O(N*k)应该比较大,因为k是可以取值到N!的,虽然通过了OJ,但是还是不太好。 网上看到一些做法,均是把它当做一道找规律的数学题目。我们知道,n个数的permutation总共有n阶乘个,基于这个性质我们可以得到某一位对应的数字是哪一个。思路是这样的,比如当前长度是n,我们知道每个相同的起始元素对应(n-1)!个permutation,也就是(n-1)!个permutation后会换一个起始元素。因此,只要当前的k进行(n-1)!取余,得到的数字就是当前剩余数组的index,如此就可以得到对应的元素。如此递推直到数组中没有元素结束。实现中我们要维护一个数组来记录当前的元素,每次得到一个元素加入结果数组,然后从剩余数组中移除,因此空间复杂度是O(n)。时间上总共需要n个回合,而每次删除元素如果是用数组需要O(n),所以总共是O(n^2)。这里如果不移除元素也需要对元素做标记,所以要判断第一个还是个线性的操作。

Code Ganker做法(未深究)

 1 public String getPermutation(int n, int k) {
 2     if(n<=0)
 3         return "";
 4     k--;
 5     StringBuilder res = new StringBuilder();
 6     int factorial = 1;
 7     ArrayList<Integer> nums = new ArrayList<Integer>();
 8     for(int i=2;i<n;i++)
 9     {
10         factorial *= i;
11     }
12     for(int i=1;i<=n;i++)
13     {
14         nums.add(i);
15     }
16     int round = n-1;
17     while(round>=0)
18     {
19         int index = k/factorial;
20         k %= factorial;
21         res.append(nums.get(index));
22         nums.remove(index);
23         if(round>0)
24             factorial /= round;
25         round--;
26     }
27     return res.toString();
28 }

 

Leetcode: Permutation Sequence

标签:style   blog   http   color   io   os   ar   for   sp   

原文地址:http://www.cnblogs.com/EdwardLiu/p/4020102.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!