:type q: TreeNode
        :rtype: TreeNode
        """
        if p.val > root.val < q.val:
            return self.lowestCommonAncestor(root.right, p, q)
        elif p.val < root.val > q.val:
            return self.lowestCommonAncestor(root.left, p, q)
        else:  #either p or q is root.val, or p and q on two sides
            return root

    # iterative - same idea.
    # assume p and q always exist
    def lowestCommonAncestor2(self, root, p, q):
        while root:
            if p.val > root.val < q.val:
                root = root.right
            elif p.val < root.val > q.val:
                root = root.left
            else:
                return root


# import
import sys, os
sys.path.insert(0, os.path.abspath((os.pardir + os.sep) * 2 + 'mylib'))
from BinaryTreeTraversalGenerator import TreeNode, build_tree_from_list
# test
root = build_tree_from_list([6, 2, 8, 0, 4, 7, 9, None, None, 3, 5])
print(Solution().lowestCommonAncestor(root, TreeNode(3), TreeNode(7)).val)
print(Solution().lowestCommonAncestor2(root, TreeNode(3), TreeNode(7)).val)
예제 #2
0
            if root:
                res.append(root.val)
                helper(root.left)
                helper(root.right)
        res = []
        helper(root)
        return res

    # generic iterative traversal
    def preorderTraversal2(self, root):
        res, stack = [], [(root, False)]
        while stack:
            node, visited = stack.pop()
            if node:
                if not visited: # append in reversed order
                    stack.append((node.right, False))
                    stack.append((node.left, False))
                    stack.append((node, True))
                else:
                    res.append(node.val)
        return res

# import
import sys, os
sys.path.insert(0, os.path.abspath((os.pardir + os.sep) * 2 + 'mylib'))
from BinaryTreeTraversalGenerator import TreeNode, build_tree_from_list
# test
root = build_tree_from_list([1,None,2,3,None])
print(Solution().preorderTraversal(root))
print(Solution().preorderTraversal2(root))
'''


# Definition for a  binary tree node
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    # @param A : root node of tree
    # @return an integer
    def isBalanced(self, root):
        def depth(root):
            return 1 + max(depth(root.left), depth(root.right)) if root else 0

        isbal = self.isBalanced
        if not root:
            return True
        depth_diff = abs(depth(root.left) - depth(root.right))
        return depth_diff <= 1 and isbal(root.left) and isbal(root.right)


# import
import sys, os
sys.path.insert(0, os.path.abspath((os.pardir + os.sep) * 2 + 'mylib'))
from BinaryTreeTraversalGenerator import TreeNode, build_tree_from_list
# test
print(Solution().isBalanced(build_tree_from_list([1, 2, 3])))
print(Solution().isBalanced(build_tree_from_list([3, 2, None, 1])))
예제 #4
0
class Solution:
    # inplace - swap left and right child and resursive invert left and right
    def invertTree(self, root):
        """
        :type root: TreeNode
        :rtype: TreeNode
        """
        if root:
            root.left, root.right = root.right, root.left
            self.invertTree(root.left)
            self.invertTree(root.right)
        return root

    # inplace - one liner
    def invertTree2(self, root):
        invert = self.invertTree2
        if root:
            root.left, root.right = invert(root.right), invert(root.left)
        return root


# import
import sys, os
sys.path.insert(0, os.path.abspath((os.pardir + os.sep) * 2 + 'mylib'))
from BinaryTreeTraversalGenerator import TreeNode, build_tree_from_list, serialize_tree_to_array
# test
root = build_tree_from_list([4, 2, 7, 1, 3, 6, 9])
print(serialize_tree_to_array(Solution().invertTree(root)))
root = build_tree_from_list([4, 2, 7, 1, 3, 6, 9])
print(serialize_tree_to_array(Solution().invertTree2(root)))
                    if leaf
                ]
        return res[::-1]

    # bfs
    def levelOrderBottom2(self, root):
        from collections import deque
        queue = deque([root])
        res = []
        while queue:
            level = []
            for _ in range(len(queue)):
                node = queue.popleft()
                if node:
                    level.append(node.val)
                    queue.append(node.left)
                    queue.append(node.right)
            if level:
                res.append(level)
        return res[::-1]


# import
import sys, os
sys.path.insert(0, os.path.abspath((os.pardir + os.sep) * 2 + 'mylib'))
from BinaryTreeTraversalGenerator import TreeNode, build_tree_from_list
# test
root = build_tree_from_list([3, 9, 20, None, None, 15, 7])
print(Solution().levelOrderBottom2(root))
print(Solution().levelOrderBottom2(root))
예제 #6
0
class Solution:
    # pass variable by reference using class variable self.
    # allow -ve node.
    def maxPathSum(self, root):
        # returns the maximum sum of the path that can be extended to input
        # node's parent.
        def get_max_sum(node):
            if not node:
                return 0
            # if path sum of a child is negative, ignore the child.
            left_sum = max(0, get_max_sum(node.left))
            right_sum = max(0, get_max_sum(node.right))
            # update the max_sum as we traverse through each node
            self.max_sum = max(self.max_sum, left_sum + right_sum + node.val)
            # only return the max of left or right as we cannot traverse both
            return max(left_sum, right_sum) + node.val

        # either use self.max_sum or non-primative type [] to pass by reference
        self.max_sum = float('-inf')
        get_max_sum(root)
        return self.max_sum


# import
import sys, os
sys.path.insert(0, os.path.abspath((os.pardir + os.sep) * 2 + 'mylib'))
from BinaryTreeTraversalGenerator import TreeNode, build_tree_from_list
# test
print(Solution().maxPathSum(build_tree_from_list([1, 2, 3])))
print(Solution().maxPathSum(build_tree_from_list([1, -2, 3])))
        while pval not in parent or qval not in parent:
            if not stack:
                return -1
            node = stack.pop()
            if node.left:
                parent[node.left.val] = node.val
                stack.append(node.left)
            if node.right:
                parent[node.right.val] = node.val
                stack.append(node.right)
        p_path = set()
        while pval:
            p_path.add(pval)
            pval = parent[pval]
        while qval not in p_path:
            qval = parent[qval]
        return qval

# import
import sys, os
sys.path.insert(0, os.path.abspath((os.pardir + os.sep) * 2 + 'mylib'))
from BinaryTreeTraversalGenerator import TreeNode, build_tree_from_list
# test
root = build_tree_from_list([3,5,1,6,2,0,8,None,None,7,4])
p = root.left.left
q = root.left.right.right
print(Solution().lowestCommonAncestor(root, p, q).val)
print(Solution().lowestCommonAncestor2(root, p, q).val)
print(Solution().lowestCommonAncestor2(root, p, q).val)
print(Solution().lca(root, 6, 4))
# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    def isSymmetric(self, root):
        # resursively compare left child and right child
        def isMirror(L, R):
            if L and R and L.val == R.val:
                return isMirror(L.left, R.right) and isMirror(L.right, R.left)
            elif L == R == None:
                return True
            else:
                return False

        return isMirror(root, root)


# import
import sys, os
sys.path.insert(0, os.path.abspath((os.pardir + os.sep) * 2 + 'mylib'))
from BinaryTreeTraversalGenerator import TreeNode, build_tree_from_list
# test
print(Solution().isSymmetric(build_tree_from_list([1, 2, 2, 3, 4, 4, 3])))
print(Solution().isSymmetric(build_tree_from_list([1, 2, 2, None, 3, None,
                                                   3])))
print(Solution().isSymmetric(build_tree_from_list([1, 2, 2, None, 3, 3,
                                                   None])))
        res = None
        for val in in_order(root):
            if not k:
                break
            res, k = val, k - 1
        return res

    # same idea without using generator
    def kthSmallest2(self, root, k):
        def helper(root):
            if root and self.k:
                helper(root.left)
                self.res = root.val
                self.k -= 1
                helper(root.right)

        self.res = None  # use self to pass primative by reference
        self.k = k  # use self to pass primative by reference
        helper(root)
        return self.res


# import
import sys, os
sys.path.insert(0, os.path.abspath((os.pardir + os.sep) * 2 + 'mylib'))
from BinaryTreeTraversalGenerator import TreeNode, build_tree_from_list
# test
root = build_tree_from_list([2, 1, 3])
print(Solution().kthSmallest(root, 2))
print(Solution().kthSmallest2(root, 2))
         1
        /
       2
max depth = 2.
'''


# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    def maxDepth(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        depth = self.maxDepth
        return 1 + max(depth(root.left), depth(root.right)) if root else 0


# import
import sys, os
sys.path.insert(0, os.path.abspath((os.pardir + os.sep) * 2 + 'mylib'))
from BinaryTreeTraversalGenerator import TreeNode, build_tree_from_list
# test
print(Solution().maxDepth(build_tree_from_list([1, 2, None])))
print(Solution().maxDepth(build_tree_from_list([3, 9, 20, None, None, 15, 7])))
예제 #11
0
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    def minDepth(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        if not root:
            return 0
        elif not root.left:
            return 1 + self.minDepth(root.right)
        elif not root.right:
            return 1 + self.minDepth(root.left)
        else:  # both right and left child exist
            return 1 + min(self.minDepth(root.left), self.minDepth(root.right))


# import
import sys, os
sys.path.insert(0, os.path.abspath((os.pardir + os.sep) * 2 + 'mylib'))
from BinaryTreeTraversalGenerator import TreeNode, build_tree_from_list
# test
print(Solution().minDepth(build_tree_from_list([1])))
print(Solution().minDepth(build_tree_from_list([1, 2])))
print(Solution().minDepth(build_tree_from_list([1, 2, 3, 4, 5])))
print(Solution().minDepth(build_tree_from_list([1, 2, 3, 4, 5, 6])))
예제 #12
0
                cur.left, cur.right = None, cur.left
            self.flatten(cur.right)  # cur.left is always empty

    # iterative & inplace - same idea but traverse to the right
    def flatten2(self, root):
        cur = root
        while cur:
            if cur.left:
                # find the inorder predecesoor of curent node
                pre = cur.left
                while pre.right:
                    pre = pre.right
                # pre is the inorder predecesoor
                pre.right = cur.right
                cur.left, cur.right = None, cur.left
            cur = cur.right  # cur.left is always empty


# import
import sys, os

sys.path.insert(0, os.path.abspath((os.pardir + os.sep) * 2 + 'mylib'))
from BinaryTreeTraversalGenerator import TreeNode, build_tree_from_list, serialize_tree_to_array
# test
root = build_tree_from_list([1, 2, 5, 3, 4, None, 6])
Solution().flatten(root)
print(serialize_tree_to_array(root))
root = build_tree_from_list([1, 2, 5, 3, 4, None, 6])
Solution().flatten2(root)
print(serialize_tree_to_array(root))
예제 #13
0
    # BFS search
    def zigzagLevelOrder2(self, root):
        from collections import deque
        queue, res = deque([root]), []
        while queue:
            level = []
            for _ in range(len(queue)):
                node = queue.popleft()
                if node:
                    level.append(node.val)
                    queue.append(node.left)
                    queue.append(node.right)
            if len(res) % 2 != 0:
                level = level[::-1]
            if level:
                res.append(level)
        return res


# import
import sys, os
sys.path.insert(0, os.path.abspath((os.pardir + os.sep) * 2 + 'mylib'))
from BinaryTreeTraversalGenerator import TreeNode, build_tree_from_list
# test
print(Solution().zigzagLevelOrder(
    build_tree_from_list([3, 9, 20, None, None, 15, 7])))
print(Solution().zigzagLevelOrder2(
    build_tree_from_list([3, 9, 20, None, None, 15, 7])))
print(Solution().zigzagLevelOrder(build_tree_from_list([])))
print(Solution().zigzagLevelOrder2(build_tree_from_list([])))