LeetCode:Permutation Sequence

题目链接:http://oj.leetcode.com/problems/permutation-sequence/

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):

"123"

"132"

"213"

"231"

"312"

"321"

Given n and k, return the kth permutation sequence.

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

在面试时需要注意咨询面试官,输入的k 是否小于1 或者 是否大于n!

分析:按照一般的递归求全排列的算法(LeetCode:Permutations),输出的序列不是按字典序有序的,比如对于1,2,3,输出序列为:

1 2 3
1 3 2
2 1 3
2 3 1
3 2 1
3 1 2

以3开头的排列举例,算法中是把1和3交换得到3 2 1,然后递归的求解,但是3 2 1不是以3开头的最小序列,应该是3 1 2. 为了得到有序的序列,我们不是把1 3 交换,而是应该把3移动到1的前面,这样得到的第一个以3开头的序列就是3 1 2。因此有如下的算法:

更多精彩内容:http://www.bianceng.cnhttp://www.bianceng.cn/Programming/sjjg/

算法1

class Solution {
private:
    int k_;
    string res_;
public:
    string getPermutation(int n, int k) {
        k_ = k;
        string str = string("123456789").substr(0, n);
        int cnt = 0;
        PermutationRecur(str, 0, cnt);
        return res_;
    }

    bool PermutationRecur(string &str, int index, int &cnt)
    {
        int len = str.size();
        if(index == len - 1)
        {
            cnt++;
            if(cnt == k_)
            {
                res_ = str;
                return true;
            }
        }
        else
        {
            for(int i = index; i < len; i++)
            {
                rotate(&str[index], &str[i], &str[i+1]);
                if(PermutationRecur(str, index + 1, cnt))
                    return true;
                rotate(&str[index], &str[i], &str[i+1]);
            }
        }
        return false;
    }
};

该算法在大数据下超时了。

算法2

利用next_permutation函数(该函数的详解请参考LeetCode:Permutations算法3),这种做法也超时了

class Solution {
public:
    string getPermutation(int n, int k) {
        string str = string("123456789").substr(0, n);
        for(int i = 1; i <= k-1; i++)
            next_permutation(str.begin(), str.end());
        return str;
    }
};

算法3

上面的算法都是逐个的求排列,有没有什么方法不是逐个求,而是直接构造出第k个排列呢?我们以n = 4,k = 17为例,数组src = [1,2,3,...,n]。

第17个排列的第一个数是什么呢:我们知道以某个数固定开头的排列个数 = (n-1)! = 3! = 6, 即以1和2开头的排列总共6*2 = 12个,12 < 17, 因此第17个排列的第一个数不可能是1或者2,6*3 > 17, 因此第17个排列的第一个数是3。即第17个排列的第一个数是原数组(原数组递增有序)的第m = upper(17/6) = 3(upper表示向上取整)个数。

第一个数固定后,我们从src数组中删除该数,那么就相当于在当前src的基础上求第k - (m-1)*(n-1)! = 17 - 2*6 = 5个排列,因此可以递归的求解该问题。

class Solution {
public:
    string getPermutation(int n, int k) {
        string str = string("123456789").substr(0, n);
        string res(n, ' ');
        for(int i = 0; i < n; i++)
            res[i] = helper(str, k);
        return res;
    }
    //以s中字符构造的全排列中,返回第k个排列的第一个字符,并且删除s中该字符
    //s中字符递增有序
    char helper(string &s, int &k)
    {
        int tmp = factorial(s.size()-1), i = (k-1)/tmp;
        char res = s[i];
        s.erase(i, 1);
        k -= i*tmp;//更新k
        return res;
    }
    //求正整数n的阶乘
    int factorial(int n)
    {
        int res = 1;
        for(int i = 2; i <= n; i++)
            res *= i;
        return res;
    }
};

当然也可以非递归实现

class Solution {
public:
    string getPermutation(int n, int k) {
        int total = factorial(n);
        string candidate = string("123456789").substr(0, n);
        string res(n,' ');
        for(int i = 0; i < n; i++)//依次计算排列的每个位
        {
            total /= (n-i);
            int index = (k-1) / total;
            res[i] = candidate[index];
            candidate.erase(index, 1);
            k -= index*total;
        }
        return res;
    }
    int factorial(int n)
    {
        int res = 1;
        for(int i = 2; i <= n; i++)
            res *= i;
        return res;
    }
};

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索算法
, 递归
, string
, int
, return
, oj
, leetcode
, str
, leetcode 注册
, 有序字典
, 数组中求第K大数
, 第K大数
K个数
sequence number、sequential、oracle sequence、mysql sequence、sequence of total,以便于您获取更多的相关知识。

时间: 2024-08-03 22:57:18

LeetCode:Permutation Sequence的相关文章

Permutation Sequence

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): "123" "132" "213" "231" "312" "3

leetcode难度及面试频率

转载自:LeetCode Question Difficulty Distribution               1 Two Sum 2 5 array sort         set Two Pointers 2 Add Two Numbers 3 4 linked list Two Pointers           Math 3 Longest Substring Without Repeating Characters 3 2 string Two Pointers      

LeetCode总结【转】

转自:http://blog.csdn.net/lanxu_yy/article/details/17848219 版权声明:本文为博主原创文章,未经博主允许不得转载. 最近完成了www.leetcode.com的online judge中151道算法题目.除各个题目有特殊巧妙的解法以外,大部分题目都是经典的算法或者数据结构,因此做了如下小结,具体的解题思路可以搜索我的博客:LeetCode题解 题目 算法 数据结构 注意事项 Clone Graph BFS 哈希表 Word Ladder II

LeetCode All in One 题目讲解汇总(持续更新中...)

终于将LeetCode的免费题刷完了,真是漫长的第一遍啊,估计很多题都忘的差不多了,这次开个题目汇总贴,并附上每道题目的解题连接,方便之后查阅吧~ 如果各位看官们,大神们发现了任何错误,或是代码无法通过OJ,或是有更好的解法,或是有任何疑问,意见和建议的话,请一定要在对应的帖子下面评论区留言告知博主啊,多谢多谢,祝大家刷得愉快,刷得精彩,刷出美好未来- 博主制作了一款iOS的应用"Leetcode Meet Me",里面有Leetcode上所有的题目,并且贴上了博主的解法,随时随地都能

LeetCode 31 Next Permutation(下一个排列)

翻译 实现"下一个排列"函数,将排列中的数字重新排列成字典序中的下一个更大的排列. 如果这样的重新排列是不可能的,它必须重新排列为可能的最低顺序(即升序排序). 重排必须在原地,不分配额外的内存. 以下是一些示例,左侧是输入,右侧是输出: 1,2,3 → 1,3,2 3,2,1 → 1,2,3 1,1,5 → 1,5,1 原文 Implement next permutation, which rearranges numbers into the lexicographically

[LeetCode]128.Longest Consecutive Sequence

[题目] Longest Consecutive Sequence  Total Accepted: 4743 Total Submissions: 17989My Submissions Given an unsorted array of integers, find the length of the longest consecutive elements sequence. For example, Given [100, 4, 200, 1, 3, 2], The longest c

[LeetCode]--31. Next Permutation

Implement next permutation, which rearranges numbers into the lexicographically next greater permutation of numbers. If such arrangement is not possible, it must rearrange it as the lowest possible order (ie, sorted in ascending order). The replaceme

UVa 11129:An antiarithmetic permutation

[链接] http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=113&page=show_problem&problem=2070 [原题] A permutation of n+1 is a bijective function of the initial n+1 natural numbers: 0, 1, ... n. A permutation p is cal

[LeetCode]58.Length of Last Word

题目 Given a string s consists of upper/lower-case alphabets and empty space characters ' ', return the length of last word in the string. If the last word does not exist, return 0. Note: A word is defined as a character sequence consists of non-space