Naive BST query.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 func searchBST (root *TreeNode, val int ) *TreeNode { var ret *TreeNode current := root for current != nil { if current.Val == val { ret = current break } else if current.Val > val { current = current.Left } else { current = current.Right } } return ret }
Since Inorder Traversal a BST we will get a sorted list, we just need to compare the previous value with current value during the traversal.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 import "math" func isValidBST (root *TreeNode) bool { previous := math.Inf(-1 ) stack := []*TreeNode{} node := root for { if node != nil { stack = append (stack, node) node = node.Left } else if len (stack) > 0 { node = stack[len (stack) - 1 ] stack = stack[:len (stack) - 1 ] if float64 (node.Val) <= previous { return false } previous = float64 (node.Val) node = node.Right } else { break } } return true }
a. In Order transverse of BST with stack, we can set up two pointers to check the difference
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 func getMinimumDifference (root *TreeNode) int { ret := 100001 var previous, current int node := root count := 0 stack := []*TreeNode{} for { if node != nil { stack = append (stack, node) node = node.Left } else if len (stack) > 0 { node = stack[len (stack) - 1 ] stack = stack[:len (stack) - 1 ] if count > 0 { previous = current } current = node.Val if count >= 1 && ret > current - previous { ret = current - previous } count++ node = node.Right } else { break } } return ret }
b. Recurrsively Inorder Traversal with two pointers
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 func getMinimumDifference (root *TreeNode) int { data := []int {} var dfs func (*TreeNode) dfs = func (node *TreeNode) { if node != nil { dfs(node.Left) data = append (data, node.Val) dfs(node.Right) } } dfs(root) min := data[1 ] - data[0 ] for i, j := 1 , 2 ; j < len (data); i, j = i + 1 , j + 1 { if min > data[j] - data[i] { min = data[j] - data[i] } } return min }
Since it’s a BST, we can get a sorted slice with inorder traversal of the tree. Once we have the sorted slice, we can use two pointers sliding window to get a mode result.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 func findMode (root *TreeNode) []int { var dfs func (*TreeNode) result := []int {} count := 1 maxCount := 1 previous := 100001 dfs = func (root *TreeNode) { if root != nil { dfs(root.Left) if previous == root.Val { count++ } else { count = 1 } if count > maxCount { maxCount = count result = []int {root.Val} } else if count == maxCount { result = append (result, root.Val) } previous = root.Val dfs(root.Right) } } dfs(root) return result }
A naive solution which can apply to all trees (not only binary tree) is we create a frequence map with a tree traversal. Then sort the map values and get the higher frequency list.
a. Pass down parent informatin layer by layer to get two slices, then find the first common items.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 var lowestCommonAncestor = function (root, p, q ) { const stack = [[root, []]]; let pPath, qPath; while (stack.length && (!pPath || !qPath)) { const [node, ancestor] = stack.shift (); const newAncestor = ancestor.concat ([node]); if (node.val === p.val ) { pPath = newAncestor; } if (node.val === q.val ) { qPath = newAncestor; } if (node.left ) { stack.push ([node.left , newAncestor]); } if (node.right ) { stack.push ([node.right , newAncestor]); } } let result = root; while (pPath.length && qPath.length ) { const x = pPath.shift (); const y = qPath.shift (); if (x.val === y.val ) { result = x; } else { break ; } } return result; };
b. If we search a tree from bottom layer to top, we can easily get the ancestor node. Postorder traversal can help us to go from bottom to up.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 func lowestCommonAncestor (root, p, q *TreeNode) *TreeNode { if root == nil || root == p || root == q { return root } left := lowestCommonAncestor(root.Left, p, q) right := lowestCommonAncestor(root.Right, p, q) if left != nil && right != nil { return root } else if left == nil { return right } return left }
Since it’s a BST, we can compare the value to remove some unnecessary calculation.
1 2 3 4 5 6 7 8 9 10 11 func lowestCommonAncestor (root, p, q *TreeNode) *TreeNode { if root != nil { if root.Val > p.Val && root.Val > q.Val { return lowestCommonAncestor(root.Left, p, q) } if root.Val < p.Val && root.Val < q.Val { return lowestCommonAncestor(root.Right, p, q) } } return root }