Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.vscode/
48 changes: 48 additions & 0 deletions binary-tree-maximum-path-sum.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package main

type TreeNode struct {
Val int
Left *TreeNode
Right *TreeNode
}

func max2(a, b int) int {
if a > b {
return a
}

return b
}

func max3(a, b, c int) int {
return max2(a, max2(b, c))
}

func traverse(root *TreeNode, maxSum *int) int {
if root == nil {
return 0
}

lPathMaxSum := traverse(root.Left, maxSum)
rPathMaxSum := traverse(root.Right, maxSum)
rootPathMaxSum := max3(root.Val, root.Val+lPathMaxSum, root.Val+rPathMaxSum)

*maxSum = max3(*maxSum, root.Val+lPathMaxSum+rPathMaxSum, rootPathMaxSum)

return rootPathMaxSum
}

func maxPathSum(root *TreeNode) int {
if root == nil {
return 0
}

maxSum := root.Val
traverse(root, &maxSum)

return maxSum
}

func main() {

}
62 changes: 62 additions & 0 deletions combination-sum-2.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package main

import (
"fmt"
"sort"
)

type Ints []int

func (ints Ints) Len() int {
return len(ints)
}

func (ints Ints) Less(i, j int) bool {
return ints[i] < ints[j]
}

func (ints Ints) Swap(i, j int) {
ints[i], ints[j] = ints[j], ints[i]
}

func findCombinations(candidates []int, target int, selectedCandidates []int, results [][]int) [][]int {
if target < 0 {
return results
}

if target == 0 {
sel := make([]int, len(selectedCandidates))
copy(sel, selectedCandidates)
results = append(results, sel)

return results
}

for i := 0; i < len(candidates); i++ {
if i > 0 && candidates[i] == candidates[i-1] {
continue
}

selectedCandidates = append(selectedCandidates, candidates[i])
results = findCombinations(candidates[i+1:], target-candidates[i], selectedCandidates, results)
selectedCandidates = selectedCandidates[:len(selectedCandidates)-1]
}

return results
}

func combinationSum2(candidates []int, target int) [][]int {
sort.Sort(Ints(candidates))

return findCombinations(candidates, target, []int{}, [][]int{})
}

func tests() {
fmt.Printf("%v\n", combinationSum2([]int{10, 1, 2, 7, 6, 1, 5}, 8))
fmt.Printf("%v\n", combinationSum2([]int{2, 5, 2, 1, 2}, 5))
fmt.Printf("%v\n", combinationSum2([]int{1, 1, 2, 2}, 5))
}

func main() {
tests()
}
85 changes: 85 additions & 0 deletions construct-binary-tree-from-preorder-and-inorder-traversal.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package main

import "fmt"

/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/

type TreeNode struct {
Val int
Left *TreeNode
Right *TreeNode
}

func getSubTree(preorder []int, preorderStart, preorderEnd int, inorder []int, inorderStart, inorderEnd int, preorderOffsetLUT, inorderOffsetLUT map[int]int) *TreeNode {
if len(preorder) == 0 || len(inorder) == 0 || preorderStart > preorderEnd || inorderStart > inorderEnd {
return nil
}

root := preorder[preorderStart]
rootInorderOffset := inorderOffsetLUT[root]
lSubTreeLen := rootInorderOffset - inorderStart

if lSubTreeLen < 0 {
fmt.Printf("****ERROR******\n")
fmt.Printf("root: %d; preorderStart: %d; inorderStart: %d; rootInorderOffset: %d; lSubTreeLen: %d\n",
root, preorderStart, inorderStart, rootInorderOffset, lSubTreeLen)

return nil
}

// fmt.Printf("getting lSubTree\n")
lSubTree := getSubTree(preorder, preorderStart+1, preorderStart+1+lSubTreeLen-1,
inorder, inorderStart, inorderStart+lSubTreeLen-1, preorderOffsetLUT, inorderOffsetLUT)

// fmt.Printf("getting rSubTree\n")
rSubTree := getSubTree(preorder, preorderStart+lSubTreeLen+1, preorderEnd,
inorder, rootInorderOffset+1, inorderEnd, preorderOffsetLUT, inorderOffsetLUT)

return &TreeNode{Val: root, Left: lSubTree, Right: rSubTree}
}

func inorderTraversal(root *TreeNode) {
if root == nil {
return
}

inorderTraversal(root.Left)
fmt.Printf("%d ", root.Val)
inorderTraversal(root.Right)
}

func buildTree(preorder []int, inorder []int) *TreeNode {
preorderOffsetLUT := make(map[int]int)
inorderOffsetLUT := make(map[int]int)

for i := 0; i < len(preorder); i++ {
preorderOffsetLUT[preorder[i]] = i
inorderOffsetLUT[inorder[i]] = i
}

return getSubTree(preorder, 0, len(preorder)-1, inorder, 0, len(inorder)-1, preorderOffsetLUT, inorderOffsetLUT)
}

func test1() {
// preorder := []int{3, 9, 20, 15, 7}
// inorder := []int{9, 3, 15, 20, 7}
preorder := []int{5, 1, 9}
inorder := []int{1, 5, 9}
// preorder := []int{1, 5}
// inorder := []int{1, 5}

tree := buildTree(preorder, inorder)

inorderTraversal(tree)
}

func main() {
test1()
}
190 changes: 190 additions & 0 deletions course-schedule-ii.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
package main

import "fmt"

type intSet struct {
size int
elements map[int]struct{}
}

func NewIntSet() intSet {
return intSet{size: 0, elements: make(map[int]struct{})}
}

func (s *intSet) Add(elem int) {
if _, exists := s.elements[elem]; !exists {
s.elements[elem] = struct{}{}
s.size++
}

return
}

func (s *intSet) Remove(elem int) {
if _, exists := s.elements[elem]; exists {
delete(s.elements, elem)
s.size--
}

return
}

func (s *intSet) Contains(elem int) bool {
_, exists := s.elements[elem]

return exists
}

func (s *intSet) GetAnyElement() (int, error) {
if len(s.elements) == 0 {
return 0, fmt.Errorf("set is empty")
}

var elem int
for k, _ := range s.elements {
elem = k

break
}

return elem, nil
}

// Return true if cycle exists.
func checkCycleFrom(start int, adjs [][]int, whiteSet, graySet, blackSet intSet) bool {
if blackSet.Contains(start) {
return false
}

if graySet.Contains(start) {
return true
}

if whiteSet.Contains(start) {
whiteSet.Remove(start)
graySet.Add(start)
}

// Explore all adjacencies
for i := 0; i < len(adjs[start]); i++ {
cycleExists := checkCycleFrom(adjs[start][i], adjs, whiteSet, graySet, blackSet)

if cycleExists {
return true
}
}

graySet.Remove(start)
blackSet.Add(start)

return false
}

func checkCycle(adjs [][]int) bool {
whiteSet, graySet, blackSet := NewIntSet(), NewIntSet(), NewIntSet()

for i := 0; i < len(adjs); i++ {
whiteSet.Add(i)
}

for {
elem, err := whiteSet.GetAnyElement()

if err != nil {
break
}

if checkCycleFrom(elem, adjs, whiteSet, graySet, blackSet) {
return true
}
}

return false
}

func topologicalTraversal(start int, adjs [][]int, visited map[int]struct{}, traversal []int) []int {
if _, exists := visited[start]; exists {
return traversal
}

for _, to := range adjs[start] {
traversal = topologicalTraversal(to, adjs, visited, traversal)
}

visited[start] = struct{}{}
traversal = append(traversal, start)

return traversal
}

func findOrder(numCourses int, prerequisites [][]int) []int {
adjs := make([][]int, numCourses)

for i, _ := range adjs {
adjs[i] = []int{}
}

visited := make(map[int]struct{})
leafCheck := make([]bool, numCourses)

for i, _ := range leafCheck {
leafCheck[i] = true
}

for _, pair := range prerequisites {
from, to := pair[0], pair[1]

adjs[from] = append(adjs[from], to)

leafCheck[to] = false
}

if checkCycle(adjs) {
return []int{}
}

order := []int{}

for i := 0; i < numCourses; i++ {
if leafCheck[i] {
// leaf course - this is a course that no other course depends on
order = topologicalTraversal(i, adjs, visited, order)
}
}

for i := 0; i < numCourses; i++ {
if _, exists := visited[i]; !exists {
return []int{}
}
}

return order
}

type testcase struct {
numCourses int
preReqs [][]int
}

func tests() {
testcases := []testcase{
testcase{numCourses: 2, preReqs: [][]int{[]int{1, 0}}},
testcase{numCourses: 4, preReqs: [][]int{[]int{1, 0}, []int{2, 0}, []int{3, 1}, []int{3, 2}}},
testcase{numCourses: 3, preReqs: [][]int{[]int{0, 2}, []int{1, 2}, []int{2, 0}}},
}

for i, tc := range testcases {
order := findOrder(tc.numCourses, tc.preReqs)

fmt.Printf("Test case: %d; order: %v\n", i, order)
}
}

func main() {
// tests()
s1 := NewIntSet()

s1.Add(4)

fmt.Printf("s1.size = %d\n", s1.size)
}
Loading