Example #1
0
from typing import List
from lwabish.algorithm.tree import TreeNode, new_tree
tcs = [
    (new_tree("3,2,3,null,3,null,1"),),
]


class Solution:
    def rob(self, root: TreeNode) -> int:
        cache = {}

        def cache_or_cal(root: TreeNode):
            result = cache.get(root, None)
            if result:
                return result
            else:
                result = do_rob(root)
                cache[root] = result
                return result

        def do_rob(root: TreeNode):
            if not root:
                return 0
            sons = cache_or_cal(root.left) + cache_or_cal(root.right)
            grand_sons = 0
            if root.left:
                grand_sons += cache_or_cal(root.left.left) + \
                    cache_or_cal(root.left.right)
            if root.right:
                grand_sons += cache_or_cal(root.right.left) + \
                    cache_or_cal(root.right.right)
Example #2
0
from typing import List, NewType
from lwabish.algorithm.tree import TreeNode, new_tree, print_tree

tcs = [
    (new_tree("1,3,2,5"), new_tree("2,1,3,null,4,null,7")),
]


class Solution:
    def mergeTrees(self, root1: TreeNode, root2: TreeNode) -> TreeNode:
        if not root1 and not root2:
            return None
        if not root1 and root2:
            return root2
        if not root2 and root1:
            return root1

        merged = TreeNode(root1.val + root2.val)
        merged.left = self.mergeTrees(root1.left, root2.left)
        merged.right = self.mergeTrees(root1.right, root2.right)
        return merged


if __name__ == '__main__':
    solution = Solution()
    for tc in tcs:
        print_tree(tc[0])
        print_tree(tc[1])
        print_tree(solution.mergeTrees(*tc))
from typing import List
from lwabish.algorithm.tree import TreeNode, new_tree
tcs = [
    (new_tree(','.join(map(lambda x: str(x),
                           [3, 9, 20, 'null', 'null', 15, 7]))), ),
]


class Solution:
    def levelOrder(self, root: TreeNode) -> List[List[int]]:
        res = list()
        if not root:
            return res

        def go(root: TreeNode, level):
            """
            leve:索引
            """
            if len(res) < level + 1:
                res.append(list())
            res[level].append(root.val)
            if root.left:
                go(root.left, level + 1)
            if root.right:
                go(root.right, level + 1)

        go(root, 0)
        return res


if __name__ == '__main__':
from typing import List
from lwabish.algorithm.tree import TreeNode, new_tree, print_tree
tcs = [
    (new_tree("4,2,7,1,3,6,9"), ),
]


class Solution:
    def invertTree(self, root: TreeNode) -> TreeNode:
        if not root:
            return None
        root.left, root.right = self.invertTree(root.right), self.invertTree(
            root.left)
        return root


if __name__ == '__main__':
    solution = Solution()
    for tc in tcs:
        print_tree(solution.invertTree(*tc))
from typing import Deque, List
from collections import deque
from lwabish.algorithm.tree import TreeNode, new_tree
tcs = [
    (new_tree(','.join(map(lambda x: str(x),
                           [3, 9, 20, 'null', 'null', 15, 7]))), ),
    (new_tree(','.join(
        map(lambda x: str(x), [
            1,
            2,
            'null',
            3,
            'null',
            4,
            'null',
            5,
        ]))), )
]


class Solution:
    def levelOrder(self, root: TreeNode) -> List[List[int]]:
        if not root:
            return []

        q = deque([root])
        level = 0

        result = []

        while q:
Example #6
0
from typing import List
from lwabish.algorithm.tree import TreeNode, new_tree
tcs = [
    (new_tree("3, 9, 20, null, null, 15, 7"),),
]


class Solution:
    def isSymmetric(self, root: TreeNode) -> bool:

        def check(left: TreeNode, right: TreeNode):
            if not left and not right:
                return True
            # 这个if里本有三种情况,但是有一种在上面已经return了
            if not left or not right:
                return False
            return left.val == right.val and check(left.left, right.right) and check(left.right, right.left)
        if not root:
            return True
        return check(root.left, root.right)


if __name__ == '__main__':
    solution = Solution()
    for tc in tcs:
        print(solution.isSymmetric(*tc))
from typing import List
from lwabish.algorithm.tree import TreeNode, new_tree
tcs = [
    (new_tree('1,null,2,3'), ),
]


class Solution:
    def inorderTraversal(self, root: TreeNode) -> List[int]:
        if root is None:
            return []
        # 从上到下拍扁:左中右
        return self.inorderTraversal(
            root.left) + [root.val] + self.inorderTraversal(root.right)


if __name__ == '__main__':
    solution = Solution()
    for tc in tcs:
        print(solution.inorderTraversal(*tc))
Example #8
0
from typing import List
from lwabish.algorithm.tree import TreeNode, new_tree
tcs = [
    (new_tree('3,5,1,6,2,0,8,null,null,7,4'), 5, 1),
]


class Solution:
    def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
        # 递归终止
        if not root or root.val == p.val or root.val == q.val:
            return root

        # dfs递归
        l = self.lowestCommonAncestor(root.left, p, q)
        r = self.lowestCommonAncestor(root.right, q, p)

        # 四种情况return不同值
        if not l and not r:
            return None
        if not l:
            return r
        if not r:
            return l
        return root


if __name__ == '__main__':
    solution = Solution()
    for tc in tcs:
        print(solution.lowestCommonAncestor(*tc))
from typing import List
from lwabish.algorithm.tree import TreeNode, new_tree, print_tree
tcs = [
    (new_tree('1,2,5,3,4,null,6'), ),
    (new_tree('1,null,2'), ),
    (new_tree('1,null,2,3'), ),
]


class Solution:
    def flatten(self, root: TreeNode) -> None:
        """
        Do not return anything, modify root in-place instead.
        """
        if not root:
            return None

        def attach_to_leaf(root1, root2):
            """
            把root2拼接到root1的尾巴上
            """
            if not root1:
                return None
            if not root1.right:
                root1.right = root2
            else:
                attach_to_leaf(root1.right, root2)

        # 对右子树进行深度优先遍历,展平
        flattened_right = self.flatten(root.right)
        # 对左子树进行深度优先遍历,展平
from typing import List
from lwabish.algorithm.tree import TreeNode, new_tree
from collections import deque
tcs = [(new_tree('3, 9, 20, null, null, 15, 7'), )]


class Solution:
    def zigzagLevelOrder(self, root: TreeNode) -> List[List[int]]:
        if not root:
            return []

        q = deque([root])
        result = []
        # 在普通的层序遍历基础上,增加一个开关表示是否反转即可
        reverse = False
        while q:
            this_level_nodes = []
            for i in range(len(q)):
                node = q.popleft()
                this_level_nodes.append(node.val)
                if node.left:
                    q.append(node.left)
                if node.right:
                    q.append(node.right)
            if reverse:
                this_level_nodes.reverse()
            result.append(this_level_nodes)
            reverse = not reverse
        return result

from typing import List
from lwabish.algorithm.tree import TreeNode, new_tree, print_tree

tcs = [
    (new_tree("1,2,3,4,5"), ),
    (new_tree(
        "4,-7,-3,null,null,-9,-3,9,-7,-4,null,6,null,-6,-6,null,null,0,6,5,null,9,null,null,-1,-4,null,null,null,-2"
    ), )
]


class Solution:
    """
    官方题解方案
    技巧:遍历时更新全局变量
    """
    def diameterOfBinaryTree(self, root: TreeNode) -> int:
        self.d = 0

        def depth(root: TreeNode):
            if not root:
                return 0
            l = depth(root.left)
            r = depth(root.right)

            # 更新全局最大值
            self.d = max(l + r, self.d)

            return max(l, r) + 1

        depth(root)
import time
from typing import List, NewType
from lwabish.algorithm.tree import TreeNode, new_tree, print_tree
tcs = [(new_tree("-10,9,20,null,null,15,7"), ),
       (new_tree("9,6,-3,null,null,-6,2,null,null,2,null,-6,-6,-6"), )]


class Solution:
    def maxPathSum(self, root: TreeNode) -> int:
        self.max_sum = root.val

        # 注意排除负值
        def do(root: TreeNode):
            if not root:
                return 0
            # 1. 计算每个节点的贡献值:空节点0,叶节点val,非叶节点val+max(左右)
            l = do(root.left)
            r = do(root.right)
            value = root.val + (max(l, r) if max(l, r) > 0 else 0)
            # 2. 用贡献值计算节点的路径和,更新全局变量:val+左贡献+右贡献(仅正贡献)
            tmp = root.val + (l if l > 0 else 0) + (r if r > 0 else 0)
            print(root.val, l, r, tmp)
            if tmp > self.max_sum:
                self.max_sum = tmp
            return value

        do(root)
        return self.max_sum


if __name__ == '__main__':