-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
/
patiencesort.go
70 lines (55 loc) · 1.47 KB
/
patiencesort.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
// Patience sorting is a sorting algorithm inspired by the card game patience.
//
// For more details check out those links below here:
// GeeksForGeeks article : https://www.geeksforgeeks.org/patience-sorting/
// Wikipedia article: https://en.wikipedia.org/wiki/Patience_sorting
// authors [guuzaa](https://github.com/guuzaa)
// worst-case time complexity: O(n log n)
// average time complexity: O(n log n)
// space complexity: O(n)
// see patiencesort.go
package sort
import "github.com/TheAlgorithms/Go/constraints"
func Patience[T constraints.Ordered](arr []T) []T {
if len(arr) <= 1 {
return arr
}
var piles [][]T
for _, card := range arr {
left, right := 0, len(piles)
for left < right {
mid := left + (right-left)/2
if piles[mid][len(piles[mid])-1] >= card {
right = mid
} else {
left = mid + 1
}
}
if left == len(piles) {
piles = append(piles, []T{card})
} else {
piles[left] = append(piles[left], card)
}
}
return mergePiles(piles)
}
func mergePiles[T constraints.Ordered](piles [][]T) []T {
var ret []T
for len(piles) > 0 {
minID := 0
minValue := piles[minID][len(piles[minID])-1]
for i := 1; i < len(piles); i++ {
if minValue <= piles[i][len(piles[i])-1] {
continue
}
minValue = piles[i][len(piles[i])-1]
minID = i
}
ret = append(ret, minValue)
piles[minID] = piles[minID][:len(piles[minID])-1]
if len(piles[minID]) == 0 {
piles = append(piles[:minID], piles[minID+1:]...)
}
}
return ret
}