我的LeetCode代码仓:https://github.com/617076674/LeetCode
原题链接:https://leetcode-cn.com/problems/permutation-sequence/description/
题目描述:
知识点:递归、回溯
思路一:求出所有的排列,取第k个排列(在LeetCode中提交会超时)
该思路之所以超时,是因为求解了许多不需要的信息。题目只要求第k个排列,可是根据该思路。我们可以求出第任意个排列。也就是说,我们在求出第k个排列的时候,额外多求了其余的排列。
时间复杂度是O(n !),空间复杂度是O(n)。
JAVA代码:
public class Solution {
List<String> list;
public String getPermutation(int n, int k) {
list = new ArrayList<>();
getPermutationUp("", 0, n, k);
return list.get(k - 1);
}
//string consists of index numbers, we are going to consider the index + 1 number
private void getPermutationUp(String string, int index, int n, int k) {
if(index == n) {
list.add(string);
return;
}
for (int i = 1; i <= n; i++) {
if(string.indexOf('0' + i) == -1) {
string += i;
getPermutationUp(string, index + 1, n, k);
string = string.substring(0, string.length() - 1);
}
}
}
}
思路二:对数组{1, 2, 3, ..., n}进行重新排列
以n = 4, k = 14的情况来举例说明该思路。
1 + {2, 3, 4} 6
2 + {1, 3, 4} 6
3 + {1, 2, 4} 6
4 + {1, 2, 3} 6
由上述可知,由1开头的排列有6个,由2开头的排列、由3开头的排列、由4开头的排列也均有6个。当我们寻找第14个排列时,势必可以确定第一个数字是3。然后我们将在{1, 2, 4}中寻找第2个排列。
1 + {2, 4} 2
2 + {1, 4} 2
4 + {1, 2} 2
由上述可知,由1开头的排列有2个,由2开头的排列、由4开头的排列也均有2个。当我们寻找第2个排列时,势必可以确定第二个数字是1。然后我们将在{2, 4}中寻找第2个排列。
2 + {4} 1
4 + {2} 1
由上述可知,由2开头的排列有1个,由4开头的排列也有1个。当我们寻找第2个排列时,势必可以确定第三个数字是4。然后我们将在{2}中寻找第1个排列。
由于{2}中只有一个数字,其第一个排列,即第四个数字必定是2。
到此,我们求出n = 4, k = 14的情况的结果是3142。
我们将上述这整一个过程用递归的形式写出来即可。
该算法的时间复杂度和空间复杂度均是O(n)级别的。
JAVA代码:
public class Solution {
public String getPermutation(int n, int k) {
int[] array = new int[n];
for (int i = 0; i < array.length; i++) {
array[i] = i + 1;
}
getPermutation(array, 0, k);
String result = "";
for (int i = 0; i < array.length; i++) {
result += array[i];
}
return result;
}
private void getPermutation(int[] array, int index, int k) {
if(k == 1) {
return;
}
int i = index;
int level = factorial(array.length - index - 1);
for (; i < array.length; i++) {
if(k - level < 1) {
break;
}
k -= level;
}
int temp = array[i];
for (int j = i - 1; j >= index; j--) {
array[j + 1] = array[j];
}
array[index] = temp;
getPermutation(array, index + 1, k);
}
//to calculate factorial of n
private int factorial(int n) {
int result = 1;
for (int i = 1; i <= n; i++) {
result *= i;
}
return result;
}
}
LeetCode解题报告: