From ea0fb1fd2016ac040de891fe45b40a41d354843a Mon Sep 17 00:00:00 2001 From: Dalmir da Silva Date: Tue, 19 Jan 2021 23:20:37 -0800 Subject: [PATCH 1/2] Add linear solution for day2. --- .gitignore | 2 ++ day2/problem.go | 19 +++++++++++++++++++ day2/problem_test.go | 15 +++++++++++++++ 3 files changed, 36 insertions(+) diff --git a/.gitignore b/.gitignore index f1c181e..ebcf844 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,5 @@ # Output of the go coverage tool, specifically when used with LiteIDE *.out +go.mod +.idea diff --git a/day2/problem.go b/day2/problem.go index 015fa7c..a2467ca 100644 --- a/day2/problem.go +++ b/day2/problem.go @@ -16,6 +16,25 @@ func ProductsExceptI(arr []int) []int { return result } +// ProductsExceptINoDivisionLinear returns an array with the products of all numbers +// except the value at the i-th position. Without using division. +// O(N) time complexity. +// O(1) space complexity. +func ProductsExceptINoDivisionLinear(arr []int) []int { + result := make([]int, len(arr)) + total := 1 + for i := 0; i < len(arr); i++ { + result[i] = total + total *= arr[i] + } + total = 1 + for i := len(arr) - 1; i >= 0; i-- { + result[i] *= total + total *= arr[i] + } + return result +} + // ProductsExceptINoDivision returns an array with the products of all numbers // except the value at the i-th position. Without using division. // O(N^2) time complexity. diff --git a/day2/problem_test.go b/day2/problem_test.go index ade59b3..1915bd5 100644 --- a/day2/problem_test.go +++ b/day2/problem_test.go @@ -21,6 +21,14 @@ func TestProductsExceptI(t *testing.T) { } } }) + t.Run("ProductsExceptINoDivisionLinear", func(t *testing.T) { + t.Parallel() + for _, tc := range testcases { + if result := ProductsExceptINoDivisionLinear(tc.input); !reflect.DeepEqual(result, tc.expected) { + t.Error("didn't get what I expected") + } + } + }) t.Run("ProductsExceptINoDivision", func(t *testing.T) { t.Parallel() for _, tc := range testcases { @@ -39,6 +47,13 @@ func BenchmarkProductsExceptI(b *testing.B) { } } }) + b.Run("ProductsExceptINoDivisionLinear", func(b *testing.B) { + for i := 0; i < b.N; i++ { + for _, tc := range testcases { + ProductsExceptINoDivisionLinear(tc.input) + } + } + }) b.Run("ProductsExceptINoDivision", func(b *testing.B) { for i := 0; i < b.N; i++ { for _, tc := range testcases { From 886b3d33817a65fb58c360868bf3be80e86e416c Mon Sep 17 00:00:00 2001 From: Dalmir da Silva Date: Wed, 20 Jan 2021 00:02:30 -0800 Subject: [PATCH 2/2] Fix day3 to consider more complex trees. --- day3/problem.go | 14 +++++---- day3/problem_test.go | 72 +++++++++++++++++++++++++++++--------------- 2 files changed, 55 insertions(+), 31 deletions(-) diff --git a/day3/problem.go b/day3/problem.go index be0fcfc..b536b4d 100644 --- a/day3/problem.go +++ b/day3/problem.go @@ -30,22 +30,24 @@ func Serialize(root *Node) string { return strings.Join(serialized, " ") } -func preorderDeserialize(serialized []string) *Node { +func preorderDeserialize(serialized []string) (*Node, int) { if len(serialized) == 0 || serialized[0] == "-1" { - return nil + return nil, 1 } v, err := strconv.Atoi(serialized[0]) if err != nil { panic("bad serialized data cannot be deserialized") } node := &Node{val: v} - node.left = preorderDeserialize(serialized[1:]) - node.right = preorderDeserialize(serialized[2:]) - return node + advanceLeft, advanceRight := 0, 0 + node.left, advanceLeft = preorderDeserialize(serialized[1:]) + node.right, advanceRight = preorderDeserialize(serialized[1+advanceLeft:]) + return node, 1 + advanceLeft + advanceRight } // Deserialize converts a string into a general binary tree. func Deserialize(data string) *Node { serialized := strings.Split(data, " ") - return preorderDeserialize(serialized) + result, _ := preorderDeserialize(serialized) + return result } diff --git a/day3/problem_test.go b/day3/problem_test.go index 69a6177..219b84d 100644 --- a/day3/problem_test.go +++ b/day3/problem_test.go @@ -1,19 +1,41 @@ package day3 import ( - // "log" "testing" ) func TestSerializeAndDeserialize(t *testing.T) { t.Parallel() - root := &Node{val: 20, - left: nil, - right: &Node{val: 8, left: nil, - right: &Node{val: 10, left: nil, - right: &Node{val: 5}}}, + root := &Node{ + val: 20, + left: &Node{ + val: 5, + left: &Node{ + val: 10, + left: nil, + right: &Node{ + val: 5, + left: nil, + right: nil, + }, + }, + right: nil, + }, + right: &Node{ + val: 8, + left: nil, + right: &Node{ + val: 10, + left: nil, + right: &Node{ + val: 5, + left: nil, + right: nil, + }, + }, + }, } - expected := "20 -1 8 -1 10 -1 5 -1 -1" + expected := "20 5 10 -1 5 -1 -1 -1 8 -1 10 -1 5 -1 -1" var result string if result = Serialize(root); result != expected { t.Errorf("Expected %v but got %v", expected, result) @@ -49,21 +71,21 @@ func TreeEquality(t1, t2 *Node) bool { } // inorder is a method to debug your inorder traversal of the tree -//func inorder(n *Node) { -//if n == nil { -//return -//} -//if n.left != nil { -//log.Println("going left") -//} else { -//log.Println("nothing to the left") -//} -//inorder(n.left) -//log.Println(n.val) -//if n.right != nil { -//log.Println("going right") -//} else { -//log.Println("nothing to the right") -//} -//inorder(n.right) -//} +// func inorder(n *Node) { +// if n == nil { +// return +// } +// if n.left != nil { +// log.Println("going left") +// } else { +// log.Println("nothing to the left") +// } +// inorder(n.left) +// log.Println(n.val) +// if n.right != nil { +// log.Println("going right") +// } else { +// log.Println("nothing to the right") +// } +// inorder(n.right) +// }