标签: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