-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path024.go
78 lines (62 loc) · 1.71 KB
/
024.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
package main
import (
"fmt"
"strconv"
"./lib"
)
// there are k! permutations of numbers 0-(k-1), i.e., we have k = 10 as we want
// to order the numbers 0-9
// 0 is the first in the lexical order
// the last 9 digits can be ordered in 9! = 362880 ways, thus the first 362880
// permutations start with 0
// the permutations 9!+1 to 2*9! start with a 1
// the permutations 2*9!+1 to 3*9! start with a 2
// thus, the millionth interval must start with a 2
/**
* n - the number of the permutation we wish to find
* k - the number of items in our list of permutations
*
* returns the segment in which the nth permutation sits and the first
* permutation in that segment
*/
func findNthPermutationSegment(n, k int) (int, int) {
fact := lib.Factorial(k-1)
var seg int
for seg = 0; seg < k; seg++ {
if seg*fact <= n && (seg+1)*fact >= n {
break;
}
}
return seg, seg*fact
}
func removeNthElement(n int, x []int) []int {
k := make([]int, len(x)-1)
for i := 0; i < len(x); i++ {
if (i == n) {
continue
}
if (i > n) {
k[i-1] = x[i]
} else {
k[i] = x[i]
}
}
return k
}
func findNthPermutation(n int, k int) int {
var nums []int
for i := 0; i < k; i++ { nums = append(nums, i) }
nthPermutation := ""
for ; len(nums) > 1; {
seg, segStart := findNthPermutationSegment(n, len(nums))
nthPermutation += strconv.Itoa(nums[seg])
n -= segStart
nums = removeNthElement(seg, nums)
}
nthPermutation += strconv.Itoa(nums[0])
r, _ := strconv.Atoi(nthPermutation)
return r
}
func main () {
fmt.Printf("Result: %d\n", findNthPermutation(1e6, 10))
}