-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathpermutation-sequence-60.java
76 lines (72 loc) · 2.21 KB
/
permutation-sequence-60.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
/**
* 回溯思想,不太会,看了解答
*
*/
class Solution {
public String getPermutation(int n, int k) {
int[] factorial = {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880};
return dfs(n, k, new boolean[n], 0, new Stack<Integer>(),factorial);
}
private String dfs(int n, int k, boolean[] used, int depth, Stack<Integer> context, int[] factorial) {
if (depth == n) {
String res = "";
for (Integer i : context) {
res += "" + i;
}
return res;
}
int ps = factorial[n-1-depth];
for (int i = 0; i < n; i++) {
if (used[i]) continue;
if (ps < k) {
k -= ps;
continue;
}
context.push(i+1);
used[i] = true;
return dfs(n, k,used, depth+1, context,factorial);
}
return "";
}
}
//解法2
class Solution {
public String getPermutation(int n, int k) {
boolean[] visited = new boolean[n];
// 将 n! 种排列分为:n 组,每组有 (n - 1)! 种排列
return recursive(n, factorial(n - 1), k, visited);
}
/**
* @param n 剩余的数字个数,递减
* @param f 每组的排列个数
*/
private String recursive(int n, int f, int k, boolean[]visited){
int offset = k%f;// 组内偏移量
int groupIndex = k/f + (offset > 0 ? 1 : 0);// 第几组
// 在没有被访问的数字里找第 groupIndex 个数字
int i = 0;
for(; i < visited.length && groupIndex > 0; i++){
if(!visited[i]){
groupIndex--;
}
}
visited[i-1] = true;// 标记为已访问
if(n - 1 > 0){
// offset = 0 时,则取第 i 组的第 f 个排列,否则取第 i 组的第 offset 个排列
return String.valueOf(i) + recursive(n-1, f/(n - 1), offset == 0 ? f : offset, visited);
}else{
// 最后一数字
return String.valueOf(i);
}
}
/**
* 求 n!
*/
private int factorial(int n){
int res = 1;
for(int i = n; i > 1; i--){
res *= i;
}
return res;
}
}