算法之第k个序列

给出集合 [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;
        }



    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值