60. Permutation Sequence

关联问题:排列1:46. Permutations, 排列2:47. Permutations II,组合:77. Combinations 

问题:

给定数字1~n,求他们组成的第k个排列。

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 for n = 3:

"123"
"132"
"213"
"231"
"312"
"321"
Given n and k, return the kth permutation sequence.

 

Example 1:
Input: n = 3, k = 3
Output: "213"

Example 2:
Input: n = 4, k = 9
Output: "2314"

Example 3:
Input: n = 3, k = 1
Output: "123"
 

Constraints:
1 <= n <= 9
1 <= k <= n!

  

解法:Backtracking(回溯算法)

对于本问题,两个变量:

  • 路径:已经选择好的前几位结果
  • 选择列表:对每个位置上元素的选择可能性0~n,排除已经visited过的元素

处理过程:

  • base:递归退出条件:选择到最后一位结束,这里为已经选择好路径长度==给出的数组长度。
    • 这里计数得到满足条件的排序,=k时,返回。
  • 做选择:对于当前位置,选择其中一个可用数字a。
    • 路径.add(a)
    • 选择列表.delete(a)
  • 撤销选择:回退到选择数字a之前的状况。
    • 路径.delete(a)
    • 选择列表.add(a)

代码参考:

 1 class Solution {
 2 public:
 3     void backtrack(string& res, int& count, int n, int k, string& path, vector<int>& visited) {
 4         if(path.size() == n) {
 5             count++;
 6             if(count==k) {
 7                 res = path;
 8             }
 9             return;
10         }
11         for(int i=0; i<n; i++) {
12             if(!visited[i]) {
13                 char opt = '1'+i;
14                 visited[i] = 1;
15                 path+=opt;
16                 backtrack(res, count, n, k, path, visited);
17                 if(res.size()>0) return;
18                 path.pop_back();
19                 visited[i] = 0;
20             }
21         }
22         return;
23     }
24     string getPermutation(int n, int k) {
25         string res;
26         string path("");
27         int count = 0;
28         vector<int> visited(n, 0);
29         backtrack(res, count, n, k, path, visited);
30         return res;
31     }
32 };
原文地址:https://www.cnblogs.com/habibah-chang/p/14230034.html