Using backtracking to find all permutations for a given array.
e.g. A = [1, 2, 3, 4]
P(A) = 1, P(2, 3, 4) + 2, P(1, 3, 4) + 3, P(1, 2, 4) + 4, P(1, 2, 3)
A for loop control the first number and a tmp list to return when tmp.size() == A.length.
Every time for loop start from 1, if tmp has element i continue else add i to the tmp list.
Backtracking every possible permutation, when cnt == k break and return. Time complexity O(n!). TLE
public class Solution {
private static int cnt;
private static boolean stop;
Solution() {
cnt = 0;
stop = false;
}
public static void backTrack(int k, int n, List<Integer> tmp, StringBuilder ret) {
if (tmp.size() == n) {
cnt++;
if (cnt == k) {
for (int t : tmp)
ret.append(t);
stop = true;
}
return;
}
else {
for (int i=1; i<=n; i++) {
if (stop) break;
if (tmp.contains(i)) continue;
tmp.add(i);
backTrack(k, n, tmp, ret);
tmp.remove(tmp.size()-1);
}
}
}
public String getPermutation(int n, int k) {
StringBuilder ret = new StringBuilder();
backTrack(k, n, new ArrayList<>(), ret);
return ret.toString();
}
}
Another approach. Find the pattern of a permutation. More efficient.
public class Solution {
public String getPermutation(int n, int k) {
int pos = 0;
List<Integer> numbers = new ArrayList<>();
int[] factorial = new int[n+1];
StringBuilder sb = new StringBuilder();
// create an array of factorial lookup
int sum = 1;
factorial[0] = 1;
for(int i=1; i<=n; i++){
sum *= i;
factorial[i] = sum;
}
// factorial[] = {1, 1, 2, 6, 24, ... n!}
// create a list of numbers to get indices
for(int i=1; i<=n; i++){
numbers.add(i);
}
// numbers = {1, 2, 3, 4}
k--;
for(int i = 1; i <= n; i++){
int index = k/factorial[n-i];
sb.append(String.valueOf(numbers.get(index)));
numbers.remove(index);
k-=index*factorial[n-i];
}
return String.valueOf(sb);
}
}