From 5e4adddff36483b49d00c34b29d1cb37689a8f29 Mon Sep 17 00:00:00 2001 From: Hoanh An Date: Mon, 30 Dec 2019 03:21:58 -0500 Subject: [PATCH] level order successor --- README.md | 3 +- gtci/level_order_successor_test.go | 115 +++++++++++++++++++++++++++++ 2 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 gtci/level_order_successor_test.go diff --git a/README.md b/README.md index 9af4c08..2bc6119 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# 104+ Coding Interview Problems with Detailed Solutions +# 105+ Coding Interview Problems with Detailed Solutions [![Go Report Card](https://goreportcard.com/badge/github.com/hoanhan101/algo) ](https://goreportcard.com/report/github.com/hoanhan101/algo) @@ -192,6 +192,7 @@ that you can prepare better for your next coding interviews. - [Level averages](gtci/level_avg_test.go) - [Minimum depth](gtci/min_depth_test.go) - [Maximum depth](gtci/max_depth_test.go) + - [Level order successor](gtci/level_order_successor_test.go) - **Other** - Data structures - Linked List diff --git a/gtci/level_order_successor_test.go b/gtci/level_order_successor_test.go new file mode 100644 index 0000000..7fc37c3 --- /dev/null +++ b/gtci/level_order_successor_test.go @@ -0,0 +1,115 @@ +/* +Problem: +- Given a binary tree and a node, find the level order successor of + the given node. The level order successor is the node that appears + right after the given node in the level order traversal. + +Example: +- Input: target=6, tree= + 1 + 2 3 + 4 5 + 6 7 + 8 + Output: 6 + +Approach: +- Similar to level order traversal problem, except we will not keep + track of all the levels. +- Instead, we keep inserting the child node to the queue and return + the next node as soon as we find the target. + +Cost: +- O(n) time, O(n) space. +*/ + +package gtci + +import ( + "testing" + + "github.com/hoanhan101/algo/common" +) + +func TestFindSuccessor(t *testing.T) { + t1 := &common.TreeNode{nil, 1, nil} + + t2 := &common.TreeNode{nil, 1, nil} + t2.Left = &common.TreeNode{nil, 2, nil} + t2.Left.Right = &common.TreeNode{nil, 3, nil} + + t3 := &common.TreeNode{nil, 1, nil} + t3.Left = &common.TreeNode{nil, 2, nil} + t3.Right = &common.TreeNode{nil, 3, nil} + + t4 := &common.TreeNode{nil, 1, nil} + t4.Left = &common.TreeNode{nil, 2, nil} + t4.Right = &common.TreeNode{nil, 3, nil} + t4.Left.Left = &common.TreeNode{nil, 4, nil} + t4.Right.Right = &common.TreeNode{nil, 5, nil} + + t5 := &common.TreeNode{nil, 1, nil} + t5.Left = &common.TreeNode{nil, 2, nil} + t5.Right = &common.TreeNode{nil, 3, nil} + t5.Left.Left = &common.TreeNode{nil, 4, nil} + t5.Right.Left = &common.TreeNode{nil, 5, nil} + t5.Right.Right = &common.TreeNode{nil, 6, nil} + t5.Left.Left.Left = &common.TreeNode{nil, 7, nil} + t5.Left.Left.Left.Left = &common.TreeNode{nil, 8, nil} + + tests := []struct { + in1 *common.TreeNode + in2 int + expected int + }{ + {t1, 1, 0}, + {t2, 2, 3}, + {t3, 2, 3}, + {t4, 4, 5}, + {t5, 6, 7}, + } + + for _, tt := range tests { + common.Equal( + t, + tt.expected, + findSuccessor(tt.in1, tt.in2), + ) + } +} + +func findSuccessor(root *common.TreeNode, target int) int { + if root == nil { + return 0 + } + + // initialize a linked list with the root. + queue := common.NewQueue() + queue.Push(root) + + for queue.Size() > 0 { + // pop the queue and cache the current value. + current := queue.Pop().(*common.TreeNode) + + // push its left child. + if current.Left != nil { + queue.Push(current.Left) + } + + // push its right child. + if current.Right != nil { + queue.Push(current.Right) + } + + if current.Value == target { + break + } + + } + + if queue.Size() > 0 { + return queue.Pop().(*common.TreeNode).Value + } + + return 0 +}