-
Notifications
You must be signed in to change notification settings - Fork 2
/
topological_sort.go
123 lines (93 loc) · 3.1 KB
/
topological_sort.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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/*
From Leetcode (https://leetcode.com/explore/challenge/card/july-leetcoding-challenge/546/week-3-july-15th-july-21st/3394/)
There are a total of n courses you have to take, labeled from 0 to n-1.
Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair: [0,1]
Given the total number of courses and a list of prerequisite pairs, return the ordering of courses you should take to finish all courses.
There may be multiple correct orders, you just need to return one of them. If it is impossible to finish all courses, return an empty array.
/*
func findOrder(numCourses int, prerequisites [][]int) []int {
if len(prerequisites) == 0 { // Handling boundary conditions
var result []int
for i := numCourses; i > 0; i-- {
result = append(result, i - 1)
}
return result
}
graph := make(map[int]*LinkedList)
for _, classPair := range prerequisites {
firstClass := classPair[1]
lastClass := classPair[0]
if _, ok := graph[lastClass]; !ok {
graph[lastClass] = new(LinkedList)
}
if _, ok := graph[firstClass]; !ok {
graph[firstClass] = NewLinkedList(lastClass)
continue
}
graph[firstClass].Add(&Node{
value: lastClass,
})
}
var (
lengths []int
nodes []int
)
for key, _ := range graph {
// fmt.Printf("Root [%d] = [%s]\n", key, PrintList(value))
// fmt.Printf("DFS[%d] = [%d]\n", key, DepthFirstSearch(graph, key))
length := DepthFirstSearch(graph, key)
lengths = append(lengths, length)
nodes = append(nodes, key)
for i := 0; i < len(lengths) - 1; i++ {
if lengths[i] < lengths[len(lengths) - 1] {
lengths[i], lengths[len(lengths) - 1] = lengths[len(lengths) - 1], lengths[i]
nodes[i], nodes[len(nodes) - 1] = nodes[len(nodes) - 1], nodes[i]
}
}
}
return nodes[:numCourses]
}
func DepthFirstSearch(graph map[int]*LinkedList, root int) int {
var result int
if _, ok := graph[root]; !ok {
return 0
}
focus := graph[root].head
for {
if focus == nil {
break
}
result++
DepthFirstSearch(graph, focus.value)
focus = focus.next
}
return result
}
type Node struct {
value int
next *Node
}
type LinkedList struct { // Could have a "visited" attribute to account for circular graphs
head *Node
}
func (l *LinkedList) Add(node *Node) {
tmp := l.head
l.head = node
l.head.next = tmp
}
func NewLinkedList(value int) *LinkedList {
var result LinkedList
result.head = &Node {
value: value,
}
return &result
}
func PrintList(list *LinkedList) string {
var result string
focus := list.head
for focus != nil {
result += fmt.Sprintf("[%d]-->", focus.value)
focus = focus.next
}
return result
}