题目:

The set [1,2,3,…,n] contains a total of n! unique permutations.

By listing and labeling all of the permutations in order,
We get the following sequence (ie, for n = 3):

  1. "123"
  2. "132"
  3. "213"
  4. "231"
  5. "312"
  6. "321"

Given n and k, return the kth permutation sequence.

Note: Given n will be between 1 and 9 inclusive.

给定n,排列成n位数,会有n!种组合,按大小排列,输出第k个数的值。

代码:

该题目看起来就不是那么复杂,但是是medium的,说明把所有的数字排出来,排序,肯定是不行的。

于是,观察规律,肯定要先确定最高位的数字。1-n无论哪一个数字在最高位,都对应(n-1)!个组合的数字。

当k>(n-1)!且k<2*(n-1),说明第一位数字是2,因为1开头的排完了,也没有排到K,但也不会比两个(n-1)!大,所以首位可以确定。

当k<(n-1)!,自然首位就是剩余元素中最小的那个。比如一开始1-n,自然就是1了。

根据该规律,分情况,递归求出每次剩余元素中应该放在首位的那个,用链表记录1-n个元素,方便删除操作,首位用栈记录(方便):

java代码,不难理解,但还是试了半天,哎。。。:

//递归求阶乘
    public int factorial(int n) {
        if(n>1) {
            n = n*factorial(n-1);
        }
        return n;
    }
    //从首位开始,递归入栈每一位对应元素
    ArrayDeque<Integer> stack=new ArrayDeque<Integer>();
    public void getFirstNum(List<Integer> num,int k) {
        int i = 1;
        int n=num.size();
        int temp = factorial(n-1);
        //每次当n为1的时候,只有一个元素了,直接入栈并退出函数
        if(n==1) {
            stack.push((Integer) num.get(0));
            System.out.println("入栈: "+(Integer) num.get(0));
            return;
        }
        //k小于(n-1)!,所以直接取链表中最小的数为首位,入栈
        if(temp >=k) {           
            stack.push((Integer) num.get(0));
            System.out.println("入栈: "+(Integer) num.get(0));
            num.remove(0);
            getFirstNum(num,k);
        }
        else {
            //k大于(n-1)!,循环找出k大于几个(n-1)!
            while (i*temp < k){
              i++;
                  //k大于i个(n-1)!,取链表中第i个位置对应的数为首位,入栈
                if(i*temp >= k) {                    
                    stack.push((Integer) num.get(i-1));                    
                    System.out.println("入栈: "+(Integer) num.get(i-1));
                    num.remove(i-1);
                    k = k-(i-1)*factorial(n-1);
                    getFirstNum(num,k);
                    break;
                }                  
            }  
        }
    }
    //获得相应位置的排列
    public String getPermutation(int n, int k) {
       if(n==0){return null;}
       int result_int = 0;
       String result_str = null;
       ArrayList<Integer> num = new ArrayList<Integer>(n);
       for (int j=1;j<=n;j++) {
           num.add(j);
       }     
       getFirstNum(num,k);
       
       while(!stack.isEmpty()) {
           result_int= result_int*10+ stack.pollLast();
       }       
       System.out.println("第"+k+"元素是: "+result_int);
       result_str = String.valueOf(result_int);
       return result_str;               
    }

结果:

60. Permutation Sequence的更多相关文章

  1. LeetCode:60. Permutation Sequence,n全排列的第k个子列

    LeetCode:60. Permutation Sequence,n全排列的第k个子列 : 题目: LeetCode:60. Permutation Sequence 描述: The set [1, ...

  2. LeetCode 31 Next Permutation / 60 Permutation Sequence [Permutation]

    LeetCode 31 Next Permutation / 60 Permutation Sequence [Permutation] <c++> LeetCode 31 Next Pe ...

  3. Leetcode 60. Permutation Sequence

    The set [1,2,3,-,n] contains a total of n! unique permutations. By listing and labeling all of the p ...

  4. leetcode 60. Permutation Sequence(康托展开)

    描述: The set [1,2,3,…,n] contains a total of n! unique permutations. By listing and labeling all of t ...

  5. 【LeetCode】60. Permutation Sequence

    题目: The set [1,2,3,…,n] contains a total of n! unique permutations. By listing and labeling all of t ...

  6. 【一天一道LeetCode】#60. Permutation Sequence.

    一天一道LeetCode系列 (一)题目 The set [1,2,3,-,n] contains a total of n! unique permutations. By listing and ...

  7. LeetCode OJ 60. Permutation Sequence

    题目 The set [1,2,3,-,n] contains a total of n! unique permutations. By listing and labeling all of th ...

  8. 60. Permutation Sequence (String; Math)

    The set [1,2,3,…,n] contains a total of n! unique permutations. By listing and labeling all of the p ...

  9. 60. Permutation Sequence(求全排列的第k个排列)

    The set [1,2,3,…,n] contains a total of n! unique permutations. By listing and labeling all of the p ...

随机推荐

  1. dwz 在dialog里打开dialog

    需要在打开dialog里再弹出一个dialog的话,需要在打开第一个dialog的地方指定rel,这样就可以弹出第二个dialog而不是替换掉第一个dialog <a class="a ...

  2. oracle数据库启动

    遇到个白痴问题,放假停电,回来时启动数据库,发现无法进入oracle管理员界面. 如下输入,但是显示的命令无效. [oracle@crm001 database]$ sqlplus / as sysd ...

  3. bootstrap实现弹出窗口

    bootstrap使用modal-dialog实现弹对话框. 一个对话框包含3部分: 对话框头部 modal-header 对话框内容体 modal-body 对话框底部 modal-footer 如 ...

  4. sqlite 去除换行符

    去除换行符操作: update t_config_list ;

  5. .Net的要知道的一些事

    1.什么是.NET?什么是CLI?什么是CLR?IL是什么?JIT是什么,它是如何工作的?GC是什么,简述一下GC的工作方式? .Net是微软推出的框架 CLI是公共语言接口(规范) CLR是公共语言 ...

  6. Code First02---CodeFirst配置实体与数据库映射的两种方式

    Code First有两种配置数据库映射的方式,一种是使用数据属性DataAnnotation,另一种是Fluent API. 这两种方式分别是什么呢?下面进行一一解释: DataAnnotation ...

  7. jQuery学习:用按键移动方块

    <!doctype html> <html> <head> <meta charset="utf-8"> <style typ ...

  8. Html中各种空格的显示

    一.使用全角空格 全角空格被解释为汉字,所以不会被被解释为HTML分隔符,可以按照实际的空格数显示. 二.使用空格的替代符号 替代符号就是在需要显示空格的地方加入替代符号,这些符号会被浏览器解释为空格 ...

  9. Android坐标系统

     1 背景 去年有很多人私信告诉我让说说自定义控件,其实通观网络上的很多博客都在讲各种自定义控件,但是大多数都是授之以鱼,却很少有较为系统性授之于渔的文章,同时由于自己也迟迟没有时间规划这一系列文章, ...

  10. qt-5.6.0 移植之实现板子与ubuntu主机通过网络进行文件传输

    经过一上午的调试以及同事的帮助,终于实现板子与主机的文件传输. 第一步关闭所有的防火墙 在 Windows 里面是在控制面板->安全->Windows 防火墙->自定义设置 在ubu ...