题目链接:https://leetcode.com/problems/permutation-sequence/
本题是在前n个自然数(1,2,...,n)进行permutations的基础上将所有排列情况按字典序排序后返回第k个,思路很清晰,可以借鉴permutations的思路,参见https://blog.csdn.net/To_be_to_thought/article/details/85168167,只不过这里按顺序生成的数生成第k个排列后,后面的递归就可以终止了,这里用一个全局逻辑变量flag来终止整个递归程序,而不是终止或返回单次递归调用。使用全局字符数组来存储排列的情况。
思路一代码如下:
class Solution {
public static char[] record;
public static boolean[] visited;
public static int count;
public static boolean flag;
public String getPermutation(int n, int k) {
flag=false;
record=new char[n];
visited=new boolean[n+1];
count=k;
recursive(0,n);
return new String(record);
}
public static void recursive(int idx,int n)
{
if(idx==n)
{
count--;
if(count==0)
flag=true;
return;
}
for(int i=1;i<=n;i++)
{
if(!visited[i] && !flag)
{
record[idx]=(char) (48+i);
visited[i]=true;
recursive(idx+1,n);
visited[i]=false;
}
}
}
}
/*Permutations的代码
class Solution {
public static List<List<Integer>> ret;
public static boolean[] visited;
public static int[] record;
public static int num;
public List<List<Integer>> permute(int[] nums) {
ret=new LinkedList<List<Integer>>();
num=nums.length;
record=new int[num];
visited=new boolean[num];
recursive(nums,num);
return ret;
}
public static void recursive(int[] nums,int k)
{
if(k==0)
{
LinkedList<Integer> tmp=new LinkedList<Integer>();
for(int i=num-1;i>=0;i--)
tmp.add(record[i]);
ret.add(tmp);
}
for(int i=0;i<nums.length;i++)
{
if(!visited[i])
{
record[k-1]=nums[i];
visited[i]=true;
recursive(nums,k-1);
visited[i]=false;
}
}
}
}
*/
这个最坏算法复杂度本质上还是O(n!),效率低下。
思路二:有时间再来整理,这个思路是看的效率最高的算法学习一下,先贴代码
class Solution {
// The permutations of {1, 2, 4} would be:
// 1 + (permutations of 2, 4
// 2 + (permutations of 1, 4)
// 4 + (permutations of 1, 2)
public String getPermutation(int n, int k) {
List<Integer> list = new ArrayList<>();
for (int i = 1; i <= n; i++) {
list.add(i);
}
int[] factorial = new int[n+1];
int sum = 1;
factorial[0] = 1;
for(int i=1; i<=n; i++){
sum *= i;
factorial[i] = sum;
}
StringBuilder sb = new StringBuilder();
k = k - 1; // change to 0-index base number
for (int i = n; i >= 1; i--) {
int index = k / factorial[i-1];
sb.append(String.valueOf(list.get(index)));
list.remove(index);
k = k - index * factorial[i-1];
}
return sb.toString();
}
}