Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Program to find kth lexicographic sequence from 1 to n of size k Python
Suppose we have two values n and k. We need to consider a list of numbers in range 1 through n [1, 2, ..., n] and generate every permutation of this list in lexicographic order. For example, if n = 4 we have [1234, 1243, 1324, 1342, 1423, 1432, 2134, 2143, 2314, 2341, 2413, 2431, 3124, 3142, 3214, 3241, 3412, 3421, 4123, 4132, 4213, 4231, 4312, 4321]. We have to find the kth value of this permutation sequence as a string.
So, if the input is like n = 4, k = 5, then the output will be "1423" (the 5th permutation in lexicographic order).
Approach
The key insight is to use factorial number system. Instead of generating all permutations, we can directly calculate which elements should be at each position based on the factorial representation of k−1 (since we use 0−based indexing internally).
The algorithm works as follows ?
Convert k−1 to factorial number system
Use these factorial digits as indices to pick elements from remaining numbers
Build the result string by selecting and removing elements
Implementation
from collections import deque
def factorial_representation(num):
"""Convert number to factorial number system"""
quo = num
res = deque([0])
i = 2
while quo:
quo, rem = divmod(quo, i)
res.appendleft(rem)
i += 1
return res
class Solution:
def solve(self, n, k):
numbers = [num for num in range(1, n + 1)]
result = ""
# Convert to 0-based indexing
k_factorial = factorial_representation(k - 1)
# Add leading zeros if needed
while len(k_factorial) < len(numbers):
result += str(numbers.pop(0))
# Use factorial digits as indices
for index in k_factorial:
number = numbers.pop(index)
result += str(number)
return result
# Test the solution
ob = Solution()
n = 4
k = 5
print(f"The {k}th lexicographic permutation of numbers 1 to {n}:")
print(ob.solve(n, k))
The 5th lexicographic permutation of numbers 1 to 4: 1423
How It Works
Let's trace through the example with n = 4, k = 5 ?
Initial numbers: [1, 2, 3, 4]
Convert k−1 = 4 to factorial system: 4 = 2×2! + 0×1! + 0×0! ? [2, 0, 0]
Since factorial digits length (3) < numbers length (4): Take first number ? result = "1", numbers = [2, 3, 4]
-
Use factorial digits as indices:
Index 2 from [2, 3, 4] ? take 4 ? result = "14", numbers = [2, 3]
Index 0 from [2, 3] ? take 2 ? result = "142", numbers = [3]
Index 0 from [3] ? take 3 ? result = "1423", numbers = []
Alternative Direct Approach
import math
def kth_permutation_direct(n, k):
"""Direct approach using factorial calculations"""
numbers = list(range(1, n + 1))
result = ""
k = k - 1 # Convert to 0-based indexing
for i in range(n):
factorial = math.factorial(n - 1 - i)
index = k // factorial
result += str(numbers.pop(index))
k = k % factorial
return result
# Test both approaches
n, k = 4, 5
print(f"Direct approach result: {kth_permutation_direct(n, k)}")
# Test with different values
n, k = 3, 4
print(f"For n=3, k=4: {kth_permutation_direct(n, k)}")
Direct approach result: 1423 For n=3, k=4: 231
Comparison
| Approach | Time Complexity | Space Complexity | Advantage |
|---|---|---|---|
| Factorial System | O(n²) | O(n) | Educational value |
| Direct Calculation | O(n²) | O(n) | More intuitive |
Conclusion
Both approaches efficiently find the kth lexicographic permutation without generating all permutations. The direct calculation method is more intuitive, while the factorial number system approach provides insight into combinatorial number systems.
