K-th Permutation of first N Natural Numbers

Last Updated : 20 May, 2026

Given two integers n and k, find the k-th permutation sequence of the first n natural numbers arranged in lexicographical order. Return the answer as a string.

Examples: 

Input: n = 4, k = 3
Output: 1324
Explanation: The permutations in lexicographical order are 1234, 1243, 1324, ..., so the 3rd permutation is 1324.

Input: n = 3, k = 5
Output: 312
Explanation: The permutations in lexicographical order are 123, 132, 213, 231, 312, 321, so the 5th permutation is 312.

Try It Yourself
redirect icon

[Naive Approach] Generate All Permutations - O(n! × n) Time and O(n!) Space

The idea is to generate all possible permutations of numbers. Store all permutations in a list, sort them lexicographically and return the k-th permutation.

  • Create a string containing numbers from 1 to n.
  • Generate all permutations recursively and store every permutation in a list.
  • Sort the list lexicographically and return the (k - 1) index permutation.
C++
#include <bits/stdc++.h>
using namespace std;

// Function to generate all permutations
void generate(string &s, int idx,
              vector<string> &res) {

    // Base case
    if (idx == s.length()) {
        res.push_back(s);
        return;
    }

    // Generate all possible permutations
    for (int i = idx; i < s.length(); i++) {

        // Swap characters
        swap(s[idx], s[i]);

        generate(s, idx + 1, res);

        // Backtrack
        swap(s[idx], s[i]);
    }
}

string kthPermutation(int n, int k) {

    string s = "";

    // Create string "123...n"
    for (int i = 1; i <= n; i++) {
        s += to_string(i);
    }

    vector<string> res;

    // Generate all permutations
    generate(s, 0, res);

    // Sort permutations lexicographically
    sort(res.begin(), res.end());

    return res[k - 1];
}

int main() {

    int n = 3, k = 5;

    cout << kthPermutation(n, k);

    return 0;
}
Java
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

class GFG {

    // Function to generate all permutations
    static void generate(StringBuilder s, int idx,
                         List<String> res) {

        // Base case
        if (idx == s.length()) {
            res.add(s.toString());
            return;
        }

        // Generate all possible permutations
        for (int i = idx; i < s.length(); i++) {

            // Swap characters
            char temp = s.charAt(idx);
            s.setCharAt(idx, s.charAt(i));
            s.setCharAt(i, temp);

            generate(s, idx + 1, res);

            // Backtrack
            temp = s.charAt(idx);
            s.setCharAt(idx, s.charAt(i));
            s.setCharAt(i, temp);
        }
    }

    static String kthPermutation(int n, int k) {

        StringBuilder s = new StringBuilder();

        // Create string "123...n"
        for (int i = 1; i <= n; i++) {
            s.append(i);
        }

        List<String> res = new ArrayList<>();

        // Generate all permutations
        generate(s, 0, res);

        // Sort permutations lexicographically
        Collections.sort(res);

        return res.get(k - 1);
    }

    public static void main(String[] args) {

        int n = 3, k = 5;

        System.out.println(kthPermutation(n, k));
    }
}
Python
# Function to generate all permutations
def generate(s, idx, res):

    # Base case
    if idx == len(s):
        res.append("".join(s))
        return

    # Generate all possible permutations
    for i in range(idx, len(s)):

        # Swap characters
        s[idx], s[i] = s[i], s[idx]

        generate(s, idx + 1, res)

        # Backtrack
        s[idx], s[i] = s[i], s[idx]


def kthPermutation(n, k):

    s = []

    # Create string "123...n"
    for i in range(1, n + 1):
        s.append(str(i))

    res = []

    # Generate all permutations
    generate(s, 0, res)

    # Sort permutations lexicographically
    res.sort()

    return res[k - 1]


if __name__ == "__main__":

    n, k = 3, 5
    print(kthPermutation(n, k))
C#
using System;
using System.Collections.Generic;

class Program {

    // Function to generate all permutations
    static void generate(char[] s, int idx,
                         List<string> res) {

        // Base case
        if (idx == s.Length) {
            res.Add(new string(s));
            return;
        }

        // Generate all possible permutations
        for (int i = idx; i < s.Length; i++) {

            // Swap characters
            char temp = s[idx];
            s[idx] = s[i];
            s[i] = temp;

            generate(s, idx + 1, res);

            // Backtrack
            temp = s[idx];
            s[idx] = s[i];
            s[i] = temp;
        }
    }

    static string kthPermutation(int n, int k) {

        string s = "";

        // Create string "123...n"
        for (int i = 1; i <= n; i++) {
            s += i.ToString();
        }

        List<string> res = new List<string>();

        // Generate all permutations
        generate(s.ToCharArray(), 0, res);

        // Sort permutations lexicographically
        res.Sort();

        return res[k - 1];
    }

    static void Main() {

        int n = 3, k = 5;

        Console.WriteLine(kthPermutation(n, k));
    }
}
JavaScript
// Function to generate all permutations
function generate(s, idx, res) {

    // Base case
    if (idx === s.length) {
        res.push(s.join(""));
        return;
    }

    // Generate all possible permutations
    for (let i = idx; i < s.length; i++) {

        // Swap characters
        [s[idx], s[i]] = [s[i], s[idx]];

        generate(s, idx + 1, res);

        // Backtrack
        [s[idx], s[i]] = [s[i], s[idx]];
    }
}

function kthPermutation(n, k) {

    let s = [];

    // Create string "123...n"
    for (let i = 1; i <= n; i++) {
        s.push(i.toString());
    }

    let res = [];

    // Generate all permutations
    generate(s, 0, res);

    // Sort permutations lexicographically
    res.sort();

    // Return k-th permutation
    return res[k - 1];
}

// Drive code
let n = 3, k = 5;
console.log(kthPermutation(n, k));

Output
312

[Expected Approach] Factorial Number System - O(n²) Time and O(n) Space

The idea is based on the observation that in all permutations of n numbers, each number appears in the first position exactly (n - 1)! times. Hence, the first digit of the k-th permutation can be directly determined using: index = k / (n - 1)!.

Once the digit is selected, it is removed from the list of available digits since it cannot be reused. The problem then reduces to finding the permutation of the remaining n - 1 digits.

Next, update k as k = k % (n - 1)! to focus only on the remaining block of permutations. This process is repeated for each position until all digits are selected.

  • Precompute factorials in an array fact[].
  • Create a nums[] array to track used digits, where 0 indicates unused and 1 indicates used.
  • Convert k into 0-based indexing by doing k = k - 1.
  • Compute the size of one permutation block using fact[n - 1].
  • Find the position using c = k / fact[n - 1] + 1, which determines the next unused digit to be selected.
  • Traverse all digits and count only those that are unused.
  • When the count reaches c, select that digit, mark it as used, and append it to the result.
  • Update k = k % fact[n - 1].
  • Repeat the same process for the remaining positions until all digits are selected.

Consider n = 3 and k = 5, initially available numbers are [1, 2, 3], after converting k into 0- based indexing k = 4, and the factorial values are 0! = 1, 1! = 1, and 2! = 2.

Step 1: Find the First Digit

  • Remaining numbers: [1, 2, 3], block size: (3 - 1)! = 2! = 2
  • Find index using: index = 4 / 2 = 2 . So, digit at index 2 is 3.
  • Answer becomes "3", remove 3 from available numbers -> [1, 2], and update: k = 4 % 2 = 0

Step 2: Find the Second Digit

  • Remaining numbers: [1, 2], block size: (2 - 1)! = 1! = 1
  • Find index using: index = 0 / 1 = 0. So, digit at index 0 is 1.
  • Answer becomes "31", remove 1 from available numbers -> [2], and update: k = 0 % 1 = 0

Step 3: Find the Last Digit

  • Only one number is left: [2]
  • Add 2 to the answer

Final answer becomes: "312"

C++
#include <bits/stdc++.h>
using namespace std;

// Function to solve recursively
string solve(int n, int k,
             vector<int> &fact,
             vector<int> &nums) {

    // Base case
    if (n == 0) {
        return "";
    }

    // Find which unused digit should come next
    int c = k / fact[n - 1] + 1;

    string str = "";

    // Traverse all digits
    for (int i = 0; i < nums.size(); i++) {

        // Count only unused digits
        c -= (nums[i] == 0 ? 1 : 0);

        // If c becomes 0, select this digit
        if (c == 0 && nums[i] == 0) {

            // Mark digit as used
            nums[i] = 1;

            // Add digit to answer
            str += to_string(i + 1);

            break;
        }
    }

    // Recursively solve for remaining digits
    return str + solve(n - 1,
                       k % fact[n - 1],
                       fact, nums);
}

string kthPermutation(int n, int k) {

    // Create factorial array
    vector<int> fact(n + 1, 1);

    for (int i = 1; i <= n; i++) {
        fact[i] = i * fact[i - 1];
    }

    // Array to track used digits
    vector<int> nums(n, 0);

    // Convert k into 0-based indexing
    k--;

    // Find kth permutation
    return solve(n, k, fact, nums);
}

int main() {

    int n = 3;
    int k = 5;

    cout << kthPermutation(n, k);

    return 0;
}
Java
import java.util.Arrays;

public class GFG {

    public static String solve(int n, int k,
                               int fact[], int nums[]) {

        // Base case
        if (n == 0) {
            return "";
        }

        // Find which unused digit should come next
        int c = k / fact[n - 1] + 1;

        String str = "";

        // Traverse all digits
        for (int i = 0; i < nums.length; i++) {

            // Count only unused digits
            c -= (nums[i] == 0 ? 1 : 0);

            // If c becomes 0, select this digit
            if (c == 0 && nums[i] == 0) {

                // Mark digit as used
                nums[i] = 1;

                // Add digit to answer
                str += String.valueOf(i + 1);

                break;
            }
        }

        // Recursively solve for remaining digits
        return str + solve(n - 1,
                           k % fact[n - 1],
                           fact, nums);
    }

    public static String kthPermutation(int n, int k) {

        // Create factorial array
        int fact[] = new int[n + 1];
        Arrays.fill(fact, 1);

        for (int i = 1; i <= n; i++) {
            fact[i] = i * fact[i - 1];
        }

        // Array to track used digits
        int nums[] = new int[n];

        // Convert k into 0-based indexing
        k--;

        // Find kth permutation
        return solve(n, k, fact, nums);
    }

    public static void main(String[] args) {

        int n = 3;
        int k = 5;

        System.out.println(kthPermutation(n, k));
    }
}
Python
# Function to solve recursively
def solve(n, k, fact, nums):

    # Base case
    if n == 0:
        return ""

    # Find which unused digit should come next
    c = k // fact[n - 1] + 1

    str1 = ""

    # Traverse all digits
    for i in range(len(nums)):

        # Count only unused digits
        c -= (1 if nums[i] == 0 else 0)

        # If c becomes 0, select this digit
        if c == 0 and nums[i] == 0:

            # Mark digit as used
            nums[i] = 1

            # Add digit to answer
            str1 += str(i + 1)

            break

    # Recursively solve for remaining digits
    return str1 + solve(n - 1,
                        k % fact[n - 1],
                        fact, nums)


def kthPermutation(n, k):

    # Create factorial array
    fact = [1] * (n + 1)

    for i in range(1, n + 1):
        fact[i] = i * fact[i - 1]

    # Array to track used digits
    nums = [0] * n

    # Convert k into 0-based indexing
    k -= 1

    # Find kth permutation
    return solve(n, k, fact, nums)


if __name__ == "__main__":

    n = 3
    k = 5

    print(kthPermutation(n, k))
C#
using System;

class GFG {

    // Function to solve recursively
    static string solve(int n, int k,
                        int[] fact, int[] nums) {

        // Base case
        if (n == 0) {
            return "";
        }

        // Find which unused digit should come next
        int c = k / fact[n - 1] + 1;

        string str = "";

        // Traverse all digits
        for (int i = 0; i < nums.Length; i++) {

            // Count only unused digits
            c -= (nums[i] == 0 ? 1 : 0);

            // If c becomes 0, select this digit
            if (c == 0 && nums[i] == 0) {

                // Mark digit as used
                nums[i] = 1;

                // Add digit to answer
                str += (i + 1).ToString();

                break;
            }
        }

        // Recursively solve for remaining digits
        return str + solve(n - 1,
                           k % fact[n - 1],
                           fact, nums);
    }

    static string kthPermutation(int n, int k) {

        // Create factorial array
        int[] fact = new int[n + 1];

        Array.Fill(fact, 1);

        for (int i = 1; i <= n; i++) {
            fact[i] = i * fact[i - 1];
        }

        // Array to track used digits
        int[] nums = new int[n];

        // Convert k into 0-based indexing
        k--;

        // Find kth permutation
        return solve(n, k, fact, nums);
    }

    static void Main() {

        int n = 3;
        int k = 5;

        Console.WriteLine(kthPermutation(n, k));
    }
}
JavaScript
// Function to solve recursively
function solve(n, k, fact, nums) {

    // Base case
    if (n === 0) {
        return "";
    }

    // Find which unused digit should come next
    let c = Math.floor(k / fact[n - 1]) + 1;

    let str = "";

    // Traverse all digits
    for (let i = 0; i < nums.length; i++) {

        // Count only unused digits
        c -= (nums[i] === 0 ? 1 : 0);

        // If c becomes 0, select this digit
        if (c === 0 && nums[i] === 0) {

            // Mark digit as used
            nums[i] = 1;

            // Add digit to answer
            str += String(i + 1);

            break;
        }
    }

    // Recursively solve for remaining digits
    return str + solve(n - 1,
                       k % fact[n - 1],
                       fact, nums);
}

function kthPermutation(n, k) {

    // Create factorial array
    let fact = new Array(n + 1).fill(1);

    for (let i = 1; i <= n; i++) {
        fact[i] = i * fact[i - 1];
    }

    // Array to track used digits
    let nums = new Array(n).fill(0);

    // Convert k into 0-based indexing
    k--;

    // Find kth permutation
    return solve(n, k, fact, nums);
}

// Drive code
let n = 3;
let k = 5;
console.log(kthPermutation(n, k));

Output
312
Comment