Skip to content

Commit 8323eaf

Browse files
Merge pull request #8 from anurag-prakash-singh/up-to-unique-paths
Up to unique paths
2 parents 09dd4b7 + 25a30e7 commit 8323eaf

27 files changed

+2521
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.vscode/

binary-tree-maximum-path-sum.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package main
2+
3+
type TreeNode struct {
4+
Val int
5+
Left *TreeNode
6+
Right *TreeNode
7+
}
8+
9+
func max2(a, b int) int {
10+
if a > b {
11+
return a
12+
}
13+
14+
return b
15+
}
16+
17+
func max3(a, b, c int) int {
18+
return max2(a, max2(b, c))
19+
}
20+
21+
func traverse(root *TreeNode, maxSum *int) int {
22+
if root == nil {
23+
return 0
24+
}
25+
26+
lPathMaxSum := traverse(root.Left, maxSum)
27+
rPathMaxSum := traverse(root.Right, maxSum)
28+
rootPathMaxSum := max3(root.Val, root.Val+lPathMaxSum, root.Val+rPathMaxSum)
29+
30+
*maxSum = max3(*maxSum, root.Val+lPathMaxSum+rPathMaxSum, rootPathMaxSum)
31+
32+
return rootPathMaxSum
33+
}
34+
35+
func maxPathSum(root *TreeNode) int {
36+
if root == nil {
37+
return 0
38+
}
39+
40+
maxSum := root.Val
41+
traverse(root, &maxSum)
42+
43+
return maxSum
44+
}
45+
46+
func main() {
47+
48+
}

combination-sum-2.go

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"sort"
6+
)
7+
8+
type Ints []int
9+
10+
func (ints Ints) Len() int {
11+
return len(ints)
12+
}
13+
14+
func (ints Ints) Less(i, j int) bool {
15+
return ints[i] < ints[j]
16+
}
17+
18+
func (ints Ints) Swap(i, j int) {
19+
ints[i], ints[j] = ints[j], ints[i]
20+
}
21+
22+
func findCombinations(candidates []int, target int, selectedCandidates []int, results [][]int) [][]int {
23+
if target < 0 {
24+
return results
25+
}
26+
27+
if target == 0 {
28+
sel := make([]int, len(selectedCandidates))
29+
copy(sel, selectedCandidates)
30+
results = append(results, sel)
31+
32+
return results
33+
}
34+
35+
for i := 0; i < len(candidates); i++ {
36+
if i > 0 && candidates[i] == candidates[i-1] {
37+
continue
38+
}
39+
40+
selectedCandidates = append(selectedCandidates, candidates[i])
41+
results = findCombinations(candidates[i+1:], target-candidates[i], selectedCandidates, results)
42+
selectedCandidates = selectedCandidates[:len(selectedCandidates)-1]
43+
}
44+
45+
return results
46+
}
47+
48+
func combinationSum2(candidates []int, target int) [][]int {
49+
sort.Sort(Ints(candidates))
50+
51+
return findCombinations(candidates, target, []int{}, [][]int{})
52+
}
53+
54+
func tests() {
55+
fmt.Printf("%v\n", combinationSum2([]int{10, 1, 2, 7, 6, 1, 5}, 8))
56+
fmt.Printf("%v\n", combinationSum2([]int{2, 5, 2, 1, 2}, 5))
57+
fmt.Printf("%v\n", combinationSum2([]int{1, 1, 2, 2}, 5))
58+
}
59+
60+
func main() {
61+
tests()
62+
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package main
2+
3+
import "fmt"
4+
5+
/**
6+
* Definition for a binary tree node.
7+
* type TreeNode struct {
8+
* Val int
9+
* Left *TreeNode
10+
* Right *TreeNode
11+
* }
12+
*/
13+
14+
type TreeNode struct {
15+
Val int
16+
Left *TreeNode
17+
Right *TreeNode
18+
}
19+
20+
func getSubTree(preorder []int, preorderStart, preorderEnd int, inorder []int, inorderStart, inorderEnd int, preorderOffsetLUT, inorderOffsetLUT map[int]int) *TreeNode {
21+
if len(preorder) == 0 || len(inorder) == 0 || preorderStart > preorderEnd || inorderStart > inorderEnd {
22+
return nil
23+
}
24+
25+
root := preorder[preorderStart]
26+
rootInorderOffset := inorderOffsetLUT[root]
27+
lSubTreeLen := rootInorderOffset - inorderStart
28+
29+
if lSubTreeLen < 0 {
30+
fmt.Printf("****ERROR******\n")
31+
fmt.Printf("root: %d; preorderStart: %d; inorderStart: %d; rootInorderOffset: %d; lSubTreeLen: %d\n",
32+
root, preorderStart, inorderStart, rootInorderOffset, lSubTreeLen)
33+
34+
return nil
35+
}
36+
37+
// fmt.Printf("getting lSubTree\n")
38+
lSubTree := getSubTree(preorder, preorderStart+1, preorderStart+1+lSubTreeLen-1,
39+
inorder, inorderStart, inorderStart+lSubTreeLen-1, preorderOffsetLUT, inorderOffsetLUT)
40+
41+
// fmt.Printf("getting rSubTree\n")
42+
rSubTree := getSubTree(preorder, preorderStart+lSubTreeLen+1, preorderEnd,
43+
inorder, rootInorderOffset+1, inorderEnd, preorderOffsetLUT, inorderOffsetLUT)
44+
45+
return &TreeNode{Val: root, Left: lSubTree, Right: rSubTree}
46+
}
47+
48+
func inorderTraversal(root *TreeNode) {
49+
if root == nil {
50+
return
51+
}
52+
53+
inorderTraversal(root.Left)
54+
fmt.Printf("%d ", root.Val)
55+
inorderTraversal(root.Right)
56+
}
57+
58+
func buildTree(preorder []int, inorder []int) *TreeNode {
59+
preorderOffsetLUT := make(map[int]int)
60+
inorderOffsetLUT := make(map[int]int)
61+
62+
for i := 0; i < len(preorder); i++ {
63+
preorderOffsetLUT[preorder[i]] = i
64+
inorderOffsetLUT[inorder[i]] = i
65+
}
66+
67+
return getSubTree(preorder, 0, len(preorder)-1, inorder, 0, len(inorder)-1, preorderOffsetLUT, inorderOffsetLUT)
68+
}
69+
70+
func test1() {
71+
// preorder := []int{3, 9, 20, 15, 7}
72+
// inorder := []int{9, 3, 15, 20, 7}
73+
preorder := []int{5, 1, 9}
74+
inorder := []int{1, 5, 9}
75+
// preorder := []int{1, 5}
76+
// inorder := []int{1, 5}
77+
78+
tree := buildTree(preorder, inorder)
79+
80+
inorderTraversal(tree)
81+
}
82+
83+
func main() {
84+
test1()
85+
}

course-schedule-ii.go

Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
package main
2+
3+
import "fmt"
4+
5+
type intSet struct {
6+
size int
7+
elements map[int]struct{}
8+
}
9+
10+
func NewIntSet() intSet {
11+
return intSet{size: 0, elements: make(map[int]struct{})}
12+
}
13+
14+
func (s *intSet) Add(elem int) {
15+
if _, exists := s.elements[elem]; !exists {
16+
s.elements[elem] = struct{}{}
17+
s.size++
18+
}
19+
20+
return
21+
}
22+
23+
func (s *intSet) Remove(elem int) {
24+
if _, exists := s.elements[elem]; exists {
25+
delete(s.elements, elem)
26+
s.size--
27+
}
28+
29+
return
30+
}
31+
32+
func (s *intSet) Contains(elem int) bool {
33+
_, exists := s.elements[elem]
34+
35+
return exists
36+
}
37+
38+
func (s *intSet) GetAnyElement() (int, error) {
39+
if len(s.elements) == 0 {
40+
return 0, fmt.Errorf("set is empty")
41+
}
42+
43+
var elem int
44+
for k, _ := range s.elements {
45+
elem = k
46+
47+
break
48+
}
49+
50+
return elem, nil
51+
}
52+
53+
// Return true if cycle exists.
54+
func checkCycleFrom(start int, adjs [][]int, whiteSet, graySet, blackSet intSet) bool {
55+
if blackSet.Contains(start) {
56+
return false
57+
}
58+
59+
if graySet.Contains(start) {
60+
return true
61+
}
62+
63+
if whiteSet.Contains(start) {
64+
whiteSet.Remove(start)
65+
graySet.Add(start)
66+
}
67+
68+
// Explore all adjacencies
69+
for i := 0; i < len(adjs[start]); i++ {
70+
cycleExists := checkCycleFrom(adjs[start][i], adjs, whiteSet, graySet, blackSet)
71+
72+
if cycleExists {
73+
return true
74+
}
75+
}
76+
77+
graySet.Remove(start)
78+
blackSet.Add(start)
79+
80+
return false
81+
}
82+
83+
func checkCycle(adjs [][]int) bool {
84+
whiteSet, graySet, blackSet := NewIntSet(), NewIntSet(), NewIntSet()
85+
86+
for i := 0; i < len(adjs); i++ {
87+
whiteSet.Add(i)
88+
}
89+
90+
for {
91+
elem, err := whiteSet.GetAnyElement()
92+
93+
if err != nil {
94+
break
95+
}
96+
97+
if checkCycleFrom(elem, adjs, whiteSet, graySet, blackSet) {
98+
return true
99+
}
100+
}
101+
102+
return false
103+
}
104+
105+
func topologicalTraversal(start int, adjs [][]int, visited map[int]struct{}, traversal []int) []int {
106+
if _, exists := visited[start]; exists {
107+
return traversal
108+
}
109+
110+
for _, to := range adjs[start] {
111+
traversal = topologicalTraversal(to, adjs, visited, traversal)
112+
}
113+
114+
visited[start] = struct{}{}
115+
traversal = append(traversal, start)
116+
117+
return traversal
118+
}
119+
120+
func findOrder(numCourses int, prerequisites [][]int) []int {
121+
adjs := make([][]int, numCourses)
122+
123+
for i, _ := range adjs {
124+
adjs[i] = []int{}
125+
}
126+
127+
visited := make(map[int]struct{})
128+
leafCheck := make([]bool, numCourses)
129+
130+
for i, _ := range leafCheck {
131+
leafCheck[i] = true
132+
}
133+
134+
for _, pair := range prerequisites {
135+
from, to := pair[0], pair[1]
136+
137+
adjs[from] = append(adjs[from], to)
138+
139+
leafCheck[to] = false
140+
}
141+
142+
if checkCycle(adjs) {
143+
return []int{}
144+
}
145+
146+
order := []int{}
147+
148+
for i := 0; i < numCourses; i++ {
149+
if leafCheck[i] {
150+
// leaf course - this is a course that no other course depends on
151+
order = topologicalTraversal(i, adjs, visited, order)
152+
}
153+
}
154+
155+
for i := 0; i < numCourses; i++ {
156+
if _, exists := visited[i]; !exists {
157+
return []int{}
158+
}
159+
}
160+
161+
return order
162+
}
163+
164+
type testcase struct {
165+
numCourses int
166+
preReqs [][]int
167+
}
168+
169+
func tests() {
170+
testcases := []testcase{
171+
testcase{numCourses: 2, preReqs: [][]int{[]int{1, 0}}},
172+
testcase{numCourses: 4, preReqs: [][]int{[]int{1, 0}, []int{2, 0}, []int{3, 1}, []int{3, 2}}},
173+
testcase{numCourses: 3, preReqs: [][]int{[]int{0, 2}, []int{1, 2}, []int{2, 0}}},
174+
}
175+
176+
for i, tc := range testcases {
177+
order := findOrder(tc.numCourses, tc.preReqs)
178+
179+
fmt.Printf("Test case: %d; order: %v\n", i, order)
180+
}
181+
}
182+
183+
func main() {
184+
// tests()
185+
s1 := NewIntSet()
186+
187+
s1.Add(4)
188+
189+
fmt.Printf("s1.size = %d\n", s1.size)
190+
}

0 commit comments

Comments
 (0)