leetcode || 60、Permutation Sequence

problem:

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.

Hide Tags
  Backtracking Math
题意:指定一个n位起始数,输出第k个下一个排列组合

thinking:

(1)直观想到调用next_permutation()函数,该函数STL已经实现,我自己也实现过(http://blog.csdn.net/hustyangju/article/details/44751293),因为next_permutation()函数的时间复杂度为O(n),所以调用该函数的时间复杂度为O(n*k),相当庞大,提交Time Limit Exceeded

(2)math 法

注意到排列组合的规律: n! = n*(n-1)!

将数组array[n] ={1,2,...,n}  ,输出序列的第一位数字在array的下标index1等于?

index1 = (k-1)/n!    

开始考虑第二位数字:

首先:k%=n!

index2 =  k/(n-1)!

....

以此类推,直到求出第n位数字的下标indexn


(3)DFS法

视决定一位数字为 1 step,深度为n,每一步确定数字的方法同 方法2,所以DFS也很容易实现


code:

math法:

Accepted 4 ms

class Solution {
public:
    string getPermutation(int n, int k) {
        vector<int> tmp;
        int count=1;
        string str;
        k--;
        for(int i=1;i<=n;i++)
        {
            tmp.push_back(i);
            count*=i;
        }
        for(int i = 0 ; i < n; i++)
        {
            vector<int>::iterator it=tmp.begin();
            count = count/(n-i);
            int selected = k / count;
            k%=count;
            str.push_back('0' + tmp[selected]);
            tmp.erase(it+selected);
        }
        return str;
     
    }

};


DFS法:
Accepted 4 ms
class Solution {
private:
    string str;
public:
    string getPermutation(int n, int k) {
        vector<int> tmp;
        str.clear();
        int count=1;
        k--;
        for(int i=1;i<=n;i++)
        {
            tmp.push_back(i);
            count*=i;
        }
        dfs(0,n,tmp,k,count);
        return str;
    }
protected:
    void dfs(int dep,int n,vector<int> &tmp, int &k,int &count)
    {
        if(dep>=n)
            return;
        vector<int>::iterator it=tmp.begin();
        count/=n-dep;
        int index=k/count;
        k%=count;
        str.push_back('0' + tmp[index]);
        tmp.erase(it+index);
        dfs(dep+1,n,tmp,k,count);
    }

};


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值