给出集合 [1,2,3,…,n],其所有元素共有 n! 种排列。
按大小顺序列出所有排列情况,并一一标记,当 n = 3 时, 所有排列如下:
“123”
“132”
“213”
“231”
“312”
“321”
给定 n 和 k,返回第 k 个排列。
说明:
给定 n 的范围是 [1, 9]。
给定 k 的范围是[1, n!]。
示例 1:
输入: n = 3, k = 3
输出: “213”
示例 2:
输入: n = 4, k = 9
输出: “2314”
暴力方式:以有序排列的方式找出前k个
怎么进行有序排列呢?
可以将 一个数字看成一个数组 比如 123456 看成{1,2,3,4,5,6}
然后每一种序列都创建一个数组给它,并且记录当前排列到哪个位置
最开始排的是cur_pos=0 ,0位可能取 1,2,3,4,5,6 这些数字,然后把后面的数字补上;然后在0位拍好后排第一位
比如:
我们从{1,2,3,4,5,6}取数
排0位的时候,我们取下了2,那么序列为2 1 3 4 5 (是一个排列,加入到全排列当中)
然后看1位,这时候剩余的数字为{1,3,4,5,6} ,那么我们可以取下任意一个,当然2 1 3 4 5 紧跟着的话,我们应该从头取,就是取下1
// //num记录能够取的数字,比如,n=4,那么 num一直为 {1,2,3,4}
// //cur_pos记录 处理到哪一个位置
// //record记录list里面加入了哪些些数字
// //list就代表了一个数字
static void add_to_list(int n,int[]num,int cur_pos,int[]record,List<Integer> list){
if(cur_pos==n){
for(int i=0;i<n;i++){
System.out.print(list.get(i)+" ");
}
System.out.print("\n");
}
for(int i=0;i<n;i++){
int[]new_record=new int[n];
new_record=record.clone();
List<Integer>new_list=new ArrayList<>(list);
if(new_record[i]==0){
//如果还没有加入,那么可以加入了
new_list.add(num[i]);
new_record[i]=1;
add_to_list(n,num,cur_pos+1,new_record,new_list);
}
}
}
class Solution {
public String getPermutation(int n, int k) {
if(n==1){
return "1";
}
String num="";
String res="";
//当前有哪些数字
for(int i=0;i<n;i++){
num+=i+1;
}
if(k==1){
return num;
}
int cur_pos=n;//用来记录当前位置 应该拿下来哪个数, 比如 cir_pos=1,str="12345",那么取下的数字为‘2’
//当前位置固定的话,有多少种排列方式?
int cnt=0;
//那么当前位置应该是第几个数?
int get_which=0;
--k;
//我已经知道一共有多少位了
while (cur_pos>0){
if(cur_pos==1){
//如果是最后一个数了
get_which=0;
}
else {
//当前位置固定的话,有多少种排列方式?
cnt=get_num_of_sort_order(cur_pos-1);
//那么当前位置应该是第几个数?
get_which=k/cnt;
k=k%cnt;
}
res+=num.charAt(get_which);
num=delete(num,get_which);
cur_pos--;
}
return res;
}
//用来获取n位数字有多少种排列方式
int get_num_of_sort_order(int n){
int res=1;
for(int i=1;i<=n;i++){
res*=i;
}
return res;
}
String delete(String num,int pos){
String res="";
for(int i=0;i<num.length();i++){
if(i!=pos){
res+=num.charAt(i);
}
}
return res;
}
}