Question
Given an n, not to output its full permutation, but to arrange all combinations from small to large, and output the kth.
Similar Questions
- Medium - 31. Next Permutation
- Medium - 46. Permutations
Solution
Take n = 4
as an example. Because it is arranged from small to large, the highest digit must be from 1 to 4. Then it can be seen as a group, we only need to look for the group number to know what the highest digit is. And the number of each group is the (n-1)!
.
When calculating the group number
, 1 to 5 divided by 6 is 0, 6 divided by 6 is 1, and 6 belongs to group 0, so we need to subtract 1 from k. By doing this, the division results are all 0.
1 | int perGroupNum = factorial(n - 1); |
Of course, there is also the question of what k
is next time. Divide the group number, and the remainder is the next k
. Because k
is counted from 1, if k
is exactly equal to a multiple of perGroupNum
, the remainder obtained at this time is 0. In fact, since we subtract 1 when we ask for groupNum
, k
should be updated to perGroupNum
at this time.
1 | k = k % perGroupNum; |
For example, if k = 6
, then groupNum = (k-1) / 6 = 0
, k % perGroupNum = 6% 6 = 0
, and the next k
can be seen from the above figure, it is obviously perGroupNum
, which is still 6.
After determining that the highest digit belongs to group 0
, then the next is the same as the above process. The only difference is that the highest digit is 2 3 4
and there is no 1
. How to get the highest digit of groupNum
needs to be considered.
We can use a list to save 1 to n from small to large, and remove one digit each time, so that we can get the number corresponding to groupNum
.
Combine then together, we get the following solution.
1 | // record `n!`, keep it here to speed up |