集合[1,2,3,...,n]总共包含n! 独特排列。 给出n和k 返回第k个排列。

来源:互联网 发布:2013年上证指数数据 编辑:程序博客网 时间:2024/05/22 03:21

本题源自LeetCode

------------------------------------------------------------------------

思路1:

回溯法  会超时

    string getPermutation(int n, int k) {        vector<string> dp;        string tmp;        backPath(dp,tmp,n,n,k);        string result=dp[dp.size()-1];        return result;    }    void backPath(vector<string> &result,string tmp,int n,int len,int k){        if(result.size()==k){            return ;        }        if(len==0)            result.push_back(tmp);        for(int i=1;i<=n;i++){            if(tmp.find(i+'0')!=string::npos)                continue;            tmp+=i+'0';            backPath(result,tmp,n,len-1,k);            tmp.erase(tmp.end()-1);        }    }

思路 2  找规律:


     在n!个排列中,第一位的元素总是(n-1)!一组出现的,也就说如果p = k / (n-1)!,
     * 那么排列的最开始一个元素一定是nums[p]。
     *
     * 假设有n个元素,第K个permutation是 a1, a2, a3, ..... ..., an 那么a1是哪一个数字呢?
     * 那么这里,我们把a1去掉,那么剩下的permutation为 a2, a3, .... .... an, 共计n-1个元素。
     * n-1个元素共有(n-1)!组排列,那么这里就可以知道 设变量K1 = K a1 = K1 / (n-1)!
     * 同理,a2的值可以推导为 a2 =K2 / (n-2)! K2 = K1 % (n-1)! ....... a(n-1) = K(n-1) / 1!
     * K(n-1) = K(n-2)/2!
     * an = K(n-1)
     */
    string getPermutation(int n, int k) {        string dict;        string res;        for(int i=1;i<=n;i++){            dict += i+'0';        }        while(n){            int p=fs(n-1);            int rows=(k-1)/p;            k=k-rows*p;            res += dict[rows];            dict.erase(dict.begin()+rows);            n=n-1;        }        return res;    }    int fs(int n){        int res=1;        for(int i=2;i<=n;i++){            res *= i;        }           return res;    }


阅读全文
0 0
原创粉丝点击