#-------------------------------------------------------------------------------
# Name: Binary Tree Level Order Traversal
# Purpose:
# Given a binary tree, return the level order traversal
# of its nodes' values. (ie, from left to right,
# then right to left for the next level and alternate between).
#
# Given binary tree {3,9,20,#,#,15,7},
# 3
# / \
# 9 20
# / \
# 15 7
#
# return its level order traversal as:
# [
# [3],
# [9,20],
# [15,7]
# ]
#-------------------------------------------------------------------------------
def levelOrder(root):
if root is None:
return []
current = [root]
rst = []
while current: # Driven by the size of root
elements, tmp = [], []
for node in current:
elements.append(node.val)
if node.left:
tmp.append(node.left)
if node.right:
tmp.append(node.right)
rst.append(elements)
current = tmp
return rst
root = to_root([3,9,20,'#','#',15,7, 1, 2, 3, '#', 5, 6])
print levelOrder(root)
#-------------------------------------------------------------------------------
# Name: Binary Tree Inorder Traversal
# Purpose:
#
# Given a binary tree, return the inorder traversal of its nodes' values.
# For example:
# Given binary tree {1,#,2,3},
# 1
# \
# 2
# /
# 3
# return [1,3,2].
#-------------------------------------------------------------------------------
def inorderTraversal2(root):
if root is None:
return []
return inorderTraversal2(root.left) + [root.val] + inorderTraversal2(root.right)
def inorderTraversal(root):
rst = []
stack = []
current = root
while current or stack:
if current:
stack.append(current)
current = current.left
else:
node = stack.pop()
rst.append(node.val)
current = node.right
return rst
root = to_root([1, '#', 2, 3])
print inorderTraversal2(root)
print inorderTraversal(root)
#-------------------------------------------------------------------------------
# Name: Binary Tree Preorder Traversal
# Purpose:
#
# Given a binary tree, return the inorder traversal of its nodes' values.
# For example:
# Given binary tree {1,#,2,3},
# 1
# \
# 2
# /
# 3
# return [1,2,3 ].
#-------------------------------------------------------------------------------
def preorderTraversal2(root):
if root is None:
return []
return [root.val] + preorderTraversal2(root.left) + preorderTraversal2(root.right)
#-------------------------------------------------------------------------------
# Name: Binary Tree Postorder Traversal
# Purpose:
#
# Given a binary tree, return the inorder traversal of its nodes' values.
# For example:
# Given binary tree {1,#,2,3},
# 1
# \
# 2
# /
# 3
# return [1,3,2].
#-------------------------------------------------------------------------------
def postorderTraversal2(root):
if root is None:
return []
return postorderTraversal2(root.left) + postorderTraversal2(root.right) + [root.val]
#-------------------------------------------------------------------------------
# Name: Same Tree
# Purpose:
#
# Given two binary trees, write a function to check if they are equal or not.
# Two binary trees are considered equal if they are structurally
# identical and the nodes have the same value.
#-------------------------------------------------------------------------------
def isSameTree(a, b):
if a is None and b is None:
return True
if None in [a, b] or a.val != b.val:
return False
return isSameTree(a.left, b.left) and isSameTree(a.right, b.right)
#-------------------------------------------------------------------------------
# Name: subTree
# Purpose: From Career Cup
#
# You have two very large binary trees: T1, with millions of nodes,
# and T2, with hundreds of nodes. Create an algorithm
# to decide if T2 is a subtree of T1.
#-------------------------------------------------------------------------------
def subTree(big, small):
if isSameTree(big, small):
return True
if big is None:
return False
return subTree(big.left, small) or subTree(big.right, small)
#-------------------------------------------------------------------------------
# Name: Maximum Depth of Binary Tree
# Purpose:
# Given a binary tree, find its maximum depth.
# The maximum depth is the number of nodes along the longest
# path from the root node down to the farthest leaf node.
#-------------------------------------------------------------------------------
def maxDepth(root, rst = 0):
if root is None:
return rst
if root.left and root.right is None:
return maxDepth(root.left, rst+1)
if root.right and root.left is None:
return maxDepth(root.right, rst+1)
return max(maxDepth(root.left, rst+1), maxDepth(root.right, rst+1))
test1 = to_root([5, 4, 8, 11, '#', 13, 4, 7, 2, '#', '#', 5, 1, 9, 9])
print maxDepth(test1)
#-------------------------------------------------------------------------------
# Name: Minimum Depth of Binary Tree
# Purpose:
#
# Given a binary tree, find its maximum depth.
# The minimum depth is the number of nodes along the longest
# path from the root node down to the farthest leaf node.
#-------------------------------------------------------------------------------
def minDepth(root, rst = 0):
if root is None:
return rst
if root.left and root.right is None:
return minDepth(root.left, rst+1)
if root.right and root.left is None:
return minDepth(root.right, rst+1)
return min(minDepth(root.left, rst+1), minDepth(root.right, rst+1))
test1 = to_root([5, 4, 8, 11, '#', 13, 4, 7, 2, '#', '#', 5, 1, 9, 9])
print minDepth(test1)
#-------------------------------------------------------------------------------
# Name: Symmetric Tree
# Purpose:
#
# Given a binary tree, check whether it is a mirror of itself
# (ie, symmetric around its center).
# For example, this binary tree is symmetric:
# 1
# / \
# 2 2
# / \ / \
# 3 4 4 3
#
# But the following is not:
# 1
# / \
# 2 2
# \ \
# 3 3
#-------------------------------------------------------------------------------
def isSymmetric(root):
if root is None:
return True
return _isSymmertric(root.left, root.right)
def _isSymmertric(left, right):
if left is None and right is None:
return True
if left is None or right is None or left.val != right.val:
return False
return _isSymmertric(left.left, right.right) and \
_isSymmertric(left.right, right.left)
root = to_root([1, 2, 2, 3, 4, 4, 3])
print isSymmetric(root)
#-------------------------------------------------------------------------------
# Name: Path Sum
# Purpose:
#
# Given a binary tree and a sum, determine if the tree has a root-to-leaf
# path such that adding up all the values along the path equals the given sum.
# For example:
# Given the below binary tree and sum = 22,
#
# 5
# / \
# 4 8
# / / \
# 11 13 4
# / \ \
# 7 2 1
#
# return true, as there exist a root-to-leaf path 5->4->11->2 which sum is 22.
#-------------------------------------------------------------------------------
def hasPathSum(root, sum):
if root is None:
return False
if root.left is None and root.right is None and sum == root.val:
return True
return hasPathSum(root.left, sum - root.val) or \
hasPathSum(root.right, sum - root.val)
root = to_root([5, 4, 8, 11, '#', 13, 4, 7, 2, '#', '#', '#', 1])
print hasPathSum(root, 22)
#-------------------------------------------------------------------------------
# Name: Path Sum II
# Purpose:
#
# Given a binary tree and a sum, find all root-to-leaf
# paths where each path's sum equals the given sum.
#
# For example:
# Given the below binary tree and sum = 22
#
# 5
# / \
# 4 8
# / / \
# 11 13 4
# / \ / \
# 7 2 5 1
#-------------------------------------------------------------------------------
class Solution:
def pathSum(self, root, sum):
return self._pathSum([], root, sum)
def _pathSum(self, current, root, sum):
if root is None:
return []
if root.left is None and root.right is None and root.val == sum:
return [current + [root.val]]
return self._pathSum(current + [root.val], root.left, sum - root.val) + \
self._pathSum(current + [root.val], root.right, sum - root.val)
a = Solution()
root = to_root([5, 4, 8, 11, '#', 13, 4, 7, 2, '#', '#', 5, 1])
print a.pathSum(root, 22)
#-------------------------------------------------------------------------------
# Name: Validate Binary Search Tree
# Purpose:
#
# Given a binary tree, determine if it is a valid binary search tree (BST).
#
# Assume a BST is defined as follows:
#
# The left subtree of a node contains only nodes with keys
# less than the node's key.
# The right subtree of a node contains only nodes with keys
# greater than the node's key.
# Both the left and right subtrees must also be binary search trees.
#
#-------------------------------------------------------------------------------
def isValidBST(root, lo = -2147483647, hi = 2147483647): # from sys import maxint
if root is None:
return True
if root.val <= lo or root.val >= hi:
return False
return isValidBST(root.left, lo, root.val) and isValidBST(root.right, root.val, hi)
test1 = to_root([4, 2, 5, 1, 3, '#', 6])
print isValidBST(test1)
def isValidBST2(root):
carry = -2147483647
for x in inorderTraversal2(root):
if x <= carry:
return False
carry = x
return True
print isValidBST2(test1)
#-------------------------------------------------------------------------------
# Name: Convert Sorted Array to Binary Search Tree
# Purpose:
#
# Given an array where elements are sorted in
# ascending order, convert it to a height balanced BST.
#-------------------------------------------------------------------------------
def sortedArrayToBST(arr):
return _sortedArrayToBST(arr, 0, len(arr)-1)
def _sortedArrayToBST(arr, lo, hi):
if lo > hi:
return None
mid =(lo + hi)/2
root = TreeNode(arr[mid])
root.left = _sortedArrayToBST(arr, lo, mid-1)
root.right = _sortedArrayToBST(arr, mid+1, hi)
return root
a = [1, 2, 3, 4, 5, 6, 7, 8]
b = [1]
root = sortedArrayToBST(a)
print inorderTraversal2(root)
root = sortedArrayToBST(b)
print inorderTraversal2(root)
#-------------------------------------------------------------------------------
# Name: Sum Root to Leaf Numbers
# Purpose
# Given a binary tree containing digits from 0-9 only,
# each root-to-leaf path could represent a number.
# An example is the root-to-leaf path 1->2->3
# which represents the number 123.
#-------------------------------------------------------------------------------
def sumNumbers(self, root, rst = 0):
if root is None:
return 0
if root.right is None and root.left is None:
return rst*10 + root.val
return self.sumNumbers(root.left, rst*10 + root.val) + \
self.sumNumbers(root.right, rst*10 + root.val)
#-------------------------------------------------------------------------------
# Name: Populating Next Right Pointers in Each Node
# Purpose:
# 1 -> NULL
# / \
# 2 -> 3 -> NULL
# / \ / \
# 4->5->6->7 -> NULL
#-------------------------------------------------------------------------------
# Definition for a binary tree node
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None
self.next = None
class Solution:
def connect(self, root):
if root is None:
return None
if root.left:
root.left.next = root.right
if root.right and root.next:
root.right.next = root.next.left
self.connect(root.left)
self.connect(root.right)