-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcount_slice_inversions.go
62 lines (54 loc) · 1.47 KB
/
count_slice_inversions.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
package count_slice_inversions
func CountSliceInversions(s []int) ([]int, int) {
totalSlice, totalInv := SortAndCountInversions(s, 0)
return totalSlice, totalInv
}
func SortAndCountInversions(s []int, inv int) ([]int, int) {
if len(s) == 1 {
return s, inv
} else {
s1, s2 := SplitSlice(s)
leftS, leftInv := SortAndCountInversions(s1, inv)
rightS, rightInv := SortAndCountInversions(s2, inv)
mergedS, mergedInv := MergeAndCountInversions(leftS, rightS)
totalInv := leftInv + rightInv + mergedInv
return mergedS, totalInv
}
}
func MergeAndCountInversions(leftS, rightS []int) ([]int, int) {
var mergedS []int
mergedInv := 0
leftI, rightI := 0, 0
for i := 0; i < len(leftS)+len(rightS); i++ {
if leftI == len(leftS) {
mergedS = append(mergedS, rightS[rightI])
rightI++
} else if rightI == len(rightS) {
mergedS = append(mergedS, leftS[leftI])
leftI++
} else if (leftI != len(leftS) && rightI != len(rightS)) && leftS[leftI] < rightS[rightI] {
mergedS = append(mergedS, leftS[leftI])
leftI++
} else if (leftI != len(leftS) && rightI != len(rightS)) && leftS[leftI] > rightS[rightI] {
mergedS = append(mergedS, rightS[rightI])
for _, v := range leftS {
rv := rightS[rightI]
if v > rv {
mergedInv++
}
}
rightI++
}
}
return mergedS, mergedInv
}
func SplitSlice (s []int) (s1, s2 []int) {
if len(s)%2 == 0 {
s1 = s[:len(s)/2]
s2 = s[len(s)/2:]
} else {
s1 = s[:(len(s)+1)/2]
s2 = s[(len(s)+1)/2:]
}
return
}