package main
import (
"container/list"
"fmt"
)
type Node struct {
Val int
Left *Node
Right *Node
}
func bottomView(root *Node) []int {
if root == nil {
return []int{}
}
hdNodeMap := make(map[int]int) // map hd to node value
queue := list.New()
type Pair struct {
node *Node
hd int
}
queue.PushBack(Pair{root, 0})
minHd, maxHd := 0, 0
for queue.Len() > 0 {
front := queue.Front()
queue.Remove(front)
pair := front.Value.(Pair)
node, hd := pair.node, pair.hd
hdNodeMap[hd] = node.Val // overwrite to keep bottom-most node
if hd < minHd {
minHd = hd
}
if hd > maxHd {
maxHd = hd
}
if node.Left != nil {
queue.PushBack(Pair{node.Left, hd - 1}) // go left: hd - 1
}
if node.Right != nil {
queue.PushBack(Pair{node.Right, hd + 1}) // go right: hd + 1
}
}
result := []int{}
for hd := minHd; hd <= maxHd; hd++ {
result = append(result, hdNodeMap[hd])
}
return result
}
func main() {
root := &Node{20, nil, nil}
root.Left = &Node{8, nil, nil}
root.Right = &Node{22, nil, nil}
root.Left.Left = &Node{5, nil, nil}
root.Left.Right = &Node{3, nil, nil}
root.Left.Right.Left = &Node{10, nil, nil}
root.Left.Right.Right = &Node{14, nil, nil}
root.Right.Right = &Node{25, nil, nil}
bv := bottomView(root)
for i, val := range bv {
if i > 0 {
fmt.Print(" -> ")
}
fmt.Print(val)
}
fmt.Println(" -> null")
}
hdNodeMap[hd] = node.Val // overwrite to keep bottom-most node
update map with current node value at horizontal distance, overwriting previous to keep bottom node
if node.Left != nil {
queue.PushBack(Pair{node.Left, hd - 1}) // go left: hd - 1
}
enqueue left child with hd decreased by 1 to track vertical position
if node.Right != nil {
queue.PushBack(Pair{node.Right, hd + 1}) // go right: hd + 1
}
enqueue right child with hd increased by 1 to track vertical position
for hd := minHd; hd <= maxHd; hd++ {
result = append(result, hdNodeMap[hd])
}
collect bottom view nodes from leftmost to rightmost horizontal distance
5 -> 10 -> 3 -> 14 -> 25 -> null