Permutation Sequence (Kth)
Initialize factorial array
Create a factorial array of size n with all elements initialized to 1. This array will store factorial values from 0! to (n-1)!.
factorial = [1] * nCompute factorial values
Compute factorial values for indices 1 and 2 by multiplying the previous factorial by the current index.
for i in range(1, n):
factorial[i] = factorial[i - 1] * iInitialize numbers list
Create a list of numbers from 1 to n to represent the available digits for the permutation.
numbers = list(range(1, n + 1))Adjust k to zero-based index
Subtract 1 from k to convert it from 1-based to zero-based indexing for easier calculations.
k -= 1 # zero-based indexCalculate index for first position
Calculate idx by dividing k by factorial[2] (2!). idx = 2 // 2 = 1. This selects the second number in the list for the first position.
idx = k // factorial[i]Update k after first selection
Update k to k modulo factorial[2], k = 2 % 2 = 0. This resets k for the next position's calculation.
k %= factorial[i]Append first chosen number and remove it
Append '2' (numbers[1]) to the result and remove it from the numbers list, leaving [1, 3].
result.append(str(numbers[idx]))
numbers.pop(idx)Calculate index for second position
Calculate idx = k // factorial[1] = 0 // 1 = 0. Select the first number in the updated list [1,3].
idx = k // factorial[i]Update k after second selection
Update k = k % factorial[1] = 0 % 1 = 0, preparing for the last digit selection.
k %= factorial[i]Append second chosen number and remove it
Append '1' (numbers[0]) to the result and remove it from the list, leaving [3].
result.append(str(numbers[idx]))
numbers.pop(idx)Calculate index for last position
Calculate idx = k // factorial[0] = 0 // 1 = 0. Select the only remaining number '3'.
idx = k // factorial[i]Append last chosen number and remove it
Append '3' to the result and remove it from the numbers list, which becomes empty.
result.append(str(numbers[idx]))
numbers.pop(idx)Return final permutation string
Join the result list into a string and return it as the kth permutation.
return ''.join(result)def getPermutation(n, k):
factorial = [1] * n # STEP 1
for i in range(1, n): # STEP 2
factorial[i] = factorial[i - 1] * i
numbers = list(range(1, n + 1)) # STEP 3
k -= 1 # zero-based index adjustment STEP 4
result = []
for i in range(n - 1, -1, -1): # STEP 5-12
idx = k // factorial[i] # STEP 5,8,11
k %= factorial[i] # STEP 6,9,12
result.append(str(numbers[idx])) # STEP 7,10,12
numbers.pop(idx)
return ''.join(result) # STEP 13
if __name__ == '__main__':
print(getPermutation(3, 3)) # Output: '213'Key Takeaways
This insight is hard to see from code alone because the math behind factorial indexing is abstract without visualization.
Seeing k and idx update step-by-step clarifies how the algorithm zooms into the correct permutation.
This concrete example shows how the numbers list changes, which is less obvious when reading code.
