leetcode60. kth permutation/dfs+pruning

Topic: 60. The kth permutation

Given the set [1,2,3,...,n], all its elements have n! permutations.

List all permutations in order of size and mark them one by one. When n = 3, all permutations are as follows:

“123”
“132”
“213”
“231”
“312”
“321”

Given n and k, return the kth permutation.

Description:

  • The range of given n is [1, 9].
  • The range of given k is [1, n!].

Example 1:

输入: n = 3, k = 3
输出: "213"

Example 2:

输入: n = 4, k = 9
输出: "2314"

Source: LeetCode (LeetCode)
Link: https://leetcode-cn.com/problems/permutation-sequence
Copyright is owned by LeetCode . For commercial reprints, please contact the official authorization. For non-commercial reprints, please indicate the source.

Basic idea: dfs+pruning

This question uses a similar idea to that of the full arrangement, but you need to modify it slightly if you want to pass this question. One is to exchange the position of the number, and the other is to prune.

Let me talk about the idea of ​​full array first:

  • Full arrangement is equivalent to the full arrangement of the first number plus the following numbers
  • Then swap each number to the first position in turn, and arrange all the numbers behind it to get the final result

The first point of this question that needs improvement:

  • Do not swap each number with the first number here. In order to comply with the order of the complete arrangement required in this question, the number needs to be deleted from the original sequence and then inserted into the position of the first number. (Note: The first position here refers to the position of pos in the function) For example: 1234, when the full arrangement starting with 4 appears first is 4123, if according to the previous full arrangement method, the first appearing is 4231 (1 and 4 Exchange), this treatment is wrong! ! !

The second point that this question needs to be improved:

  • Pruning operation: Because we know that we are looking for the kth permutation, we can use how many permutations that start with this number to perform pruning.
    For example: 1234, we need to find the 9th permutation, first there are 6 starting with 1 (that is, the full permutation of 234), 6 <9, so the 9th permutation must not start with 1, then we need to find the next whole The third permutation;
    next, look for the full permutation starting with 2. There are still 6, 6>3, then the ninth permutation starts with 2. In the same way, determine each of the next digits in turn.
class Solution {
    
    
public:
    
    string cur = "";
    int qn;
    string getPermutation(int n, int k) {
    
    
        string nums = "";
        for(int i = 0; i < n; ++i){
    
    
            nums += ((i + 1) + '0');
        }
        qn = n;
        int cnt = k;
        dfs(nums, 0, cnt);
        
        return cur;
    }
    bool dfs(string nums, int pos, int &cnt){
    
    
        if(cnt == 1){
    
    
            cur = nums;
            return true;
        }

        bool flag = false;
        //第一个数字加上其后面数字的全排列
        //依次将每一个数字放在第一位,对其后面的数字进行全排列
        
        for(int i = pos; i < qn && !flag; ++i){
    
    
            //剪枝
            //计算以该数字开头的全排列的个数
            int sum_pos = fun(qn - pos - 1);
            if(sum_pos < cnt){
    
    
                cnt -= sum_pos;
                continue;
            }

            //将当前字符从字符串中删除,插入到pos指示的位置
            string cur = nums;              
            char t = nums[i];
            cur.erase(cur.begin() + i);
            cur.insert(cur.begin() + pos, t);

            flag = dfs(cur, pos + 1, cnt);
        }
        return flag;
    }
    int fun(int num){
    
    
        int res = 1;
        while(num){
    
    
            res *= num;
            num--; 
        }
        return res;
    }
};

Guess you like

Origin blog.csdn.net/qq_31672701/article/details/108424433
Recommended