LeetCode Notebook 2020-2021
  • 序
  • 目录
  • 线性表
    • 数组
      • Remove Duplicates from Sorted Array
      • Remove Duplicates from Sorted Array II
      • Exercises I
      • Search in Rotated Sorted Array
      • Search in Rotated Sorted Array II
      • Median of Two Sorted Arrays
      • Longest Consecutive Sequence
      • Exercises II
      • Two Sum
      • 3Sum
      • 3Sum Closest
      • 4Sum
      • Exercises III
      • Next Permutation
      • Permutation Sequence
      • Exercises IV
      • Valid Sudoku
      • Trapping Rain Water
      • Rotate Image
      • Plus One
      • Exercises V
      • Climbing Stairs
      • Set Matrix Zeroes
      • Gray Code
      • Gas Station
      • Exercises VI
      • Candy
      • Single Number
      • Single Number II
      • Exercises VII
    • 链表
      • Add Two Numbers
      • Reverse Linked List II
      • Partition List
      • Swap-nodes-in-pairs
  • 字符串
    • 字符串
      • Valid Palindrome
      • Implement strStr()
      • String to Integer(atoi)
      • Add Binary
      • Longest Palindromic Substring
      • Longest Common Subsequence
      • Regular Expression Matching
      • Rearrange Spaces Between Words
      • Longest Common Prefix
      • Wildcard Matching
      • subdomain visit count
  • 栈和队列
    • 栈
      • Min Stack
      • Valid Parentheses
    • 队列
  • 树
    • 二叉树的遍历
      • Binary Tree Preorder Traversal
      • Binary Tree Inorder Traversal
      • Binary Tree Postorder Traversal
      • Search in a Binary Search Tree
    • 二叉树的构造
      • Untitled
    • 二叉查找树
      • Validate Binary Search Tree
    • 二叉树的递归
      • Untitled
  • 图
    • 图
  • 排序
    • 排序
      • Merge Sorted Array
      • Merge Two Sorted Lists
      • Merge k Sorted Lists
      • Exercises I
      • Insertion Sort List
      • Sort List
      • Sort Color
      • First Missing Positive
      • Exercises II
  • 查找
    • 查找
      • Random Pick with Weight
      • Prefix and Suffix Search
      • Search Insert Position
      • Search a 2D Matrix
  • BFS
    • BFS
  • DFS
    • DFS
      • Split a String Into the Max Number of Unique Substrings
      • Palindrome Partitioning
      • Unique Path
      • Unique Path II
  • 动态规划
    • DP
      • Coin Change
      • Maximal Rectangle
      • Super Egg Drop
      • Exercises
      • Best Team With No Conflicts
  • 分治法
    • Divide And Conquer
  • 贪心法
    • Greedy
      • Jump Game
      • Jump Game II
      • Best time to buy and sell stock
      • Best time to buy and sell stock II
      • Container with most water
      • Exercises
  • 暴力枚举
    • Brute Force
      • Subsets
      • Subsets II
      • Permutation
      • Permutation II
      • Combinations
      • Letter Combinations of a Phone Number
  • others
    • 小岛题
    • 滑动窗口
      • Longest substring without repeating characters
      • Sliding Window Maximum
      • Max Consecutive One III
      • Count Number of Nice Subarrays
    • Roman number code
    • Untitled
由 GitBook 提供支持
在本页
  • Permutation Sequence
  • 描述
  • 例子
  • Note
  • 解法一
  • 解法二
  • 解法三 backtracking

这有帮助吗?

  1. 线性表
  2. 数组

Permutation Sequence

hard 原题链接:https://leetcode.com/problems/permutation-sequence/

上一页Next Permutation下一页Exercises IV

最后更新于4年前

这有帮助吗?

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

  1. "123"

  2. "132"

  3. "213"

  4. "231"

  5. "312"

  6. "321"

Given n and k, return the kth permutation sequence.

例子

Input: n = 3, k = 3

Output: "213"

Input: n = 4, k = 9

Output: "2314"

Note

  • Given n will be between 1 and 9 inclusive.

  • Given k will be between 1 and n! inclusive.

解法一

class Solution {
public:
    string getPermutation(int n, int k) {
        string s = "", res = "";
        vector<int>factorial(n + 1, 1);
        int sum = 1;
        for(int i = 1; i <= n; i++){
            s.push_back(i + '0');
            sum *= i;
            factorial[i] = sum;
        }
        k--;
        for(int i = 1; i <= n; i++){
            int index = k / factorial[n - i];
            res.push_back(s[index]);
            s.erase(s.begin() + index);
            k %= factorial[n - i];
        }
        return res;
    }
};

The approach is mathematical. The idea is to keep selecting a digit and eliminating it from further selection based on value of K.

For example:

Given, N = 4, K = 9

There are 6 numbers starting with 1: 1234, 1243, 1324, 1342, 1423, 1432 There are 6 numbers starting with 2: 2134, 2143, 2314, 2341, 2413, 2431 Similarly, there are 6 numbers starting with 3 and 6 numbers starting with 4.

This is because when we have chosen one place out of 4 places (as N=4), there are 3 places remaining to be filled and those 3 places can be filled in 6 ways or (N-1)! ways.

So, we have to keep identifying which digit to choose.

Initially, we have to choose a digit from {1,2,3,4}.

Since K = 9, meaning it belongs to second set of six numbers and hence, would begin with 2.

Now, first place is chosen as 2 and output string becomes "2". This means we have eliminated 6 choices starting with 1 (1234, 1243, 1324, 1342, 1423, 1432).

Now, K would be updated as K = 9 - 6 = 3.

We now have to identify remaining 3 places with the digits {1,3,4} and with K = 3.

There are 2 numbers starting with 1: 134, 143 There are 2 numbers starting with 3: 314, 341 There are 2 numbers starting with 4: 413, 431

This is because when we have chosen one place out of 3 available places, there are 2 places remaining to be filled and those 2 places can be filled in 2 ways.

Since, K = 3, meaning it belongs to second set of two numbers and hence, answer would be appended with "3" and output string becomes "23". This means we have eliminated 2 choices starting with 1 (134, 143).

Now, K would be updated as K = 3 - 2 = 1.

We now have to identify remaining 2 places with the digits {1,4} with K = 1.

There is 1 number starting with 1: 14 There is 1 number starting with 4: 41

This is because when we have chosen one place out of 2 available places, there is only 1 place remaining to be filled and that 1 place can be only be filled in 1 ways.

Since, K = 1, meaning it belongs to first set of one number and hence, answer would be appended with "14" and output string becomes "2314".

Therefore, final answer becomes "2314".

解法二

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

解法三 backtracking

class Solution {
public:
    string getPermutation(int n, int k) {
        string s = "", res = "";
        for(int i = 1; i <= n; i++) s.push_back(i + '0');
        string path = s;
        int count = 0;
        DFS(s, 0, count, n, k, path, res);
        return res;
    }
    
    void DFS(string& s, int pos, int& count, int n, int k, string& path, string& res){
        if(count >= k || pos == n){
            if(++count == k) res = path;
            return;
        }
        for(int i = 0; i < n; i++){
            if(s[i] == '0') continue;
            path[pos] = s[i];
            s[i] = '0';
            DFS(s, pos + 1, count, n, k, path, res);
            s[i] = path[pos];
        }
    }
};

原题链接
出处
next_permutation