LeetCode刷题笔记

LeetCode刷题笔记(四)二叉树

2021-08-09  本文已影响0人  YongtaoHuang

四. 二叉树

Leetcode中的链表有一个ListNode类,我很好奇它是怎么实现的?还有树的TreeNode类。上述两者,我没有找到具体实现的代码,有人知道欢迎评论告知,感谢。
其实二叉树的许多问题,用递归的解法,代码可读性强又好理解。但是也存在因递归深度太大导致的内存占用量大的问题。注意以下两个知识点:

def recursion(level, param1, param2, ...):
    # recursion terminator
    if level > MAX_LEVEL:
        print_result
        return
    # process logic in current level
    process_data(level, data...)
    # drill down
    self.recursion(level+1, p1, ...)
    # reverse the current level status if needed
    reverse_state(level)
144. 二叉树的前序遍历

题目:前序遍历

    def preorderTraversal(self, root: TreeNode) -> List[int]:
        if not root:
            return []
        res = list()
        self.preorder(root, res) # 递归解法
        return res

    def preorder(self, node: TreeNode, res: List[int]) -> None:
        if not node: 
            return
        res.append(node.val) # 当前
        self.preorder(node.left, res) # 左子树
        self.preorder(node.right, res) # 右子树
    def preorderTraversal(self, root: TreeNode) -> List[int]:
        if not root:
            return []
        cur, stack, res = root, [], []
        while cur or stack: # 迭代解法
            while cur: # 根节点和左孩子入栈
                res.append(cur.val)
                stack.append(cur)
                cur = cur.left
            tmp = stack.pop() # 每次弹出一个元素,就到达右孩子
            cur = tmp.right
        
        return res
94. 二叉树的中序遍历

题目:中序遍历

    def inorderTraversal(self, root: TreeNode) -> List[int]:
        if not root:
            return []
        res = list()
        self.inorder(root, res) # 递归解法
        return res

    def inorder(self, node: TreeNode, res: List[int]) -> None:
        if not node: 
            return
        self.inorder(node.left, res) # 左子树
        res.append(node.val)  # 当前
        self.inorder(node.right, res)  # 右子树
    def inorderTraversal(self, root: TreeNode) -> List[int]:
        if not root:
            return []
        cur, stack, res = root, [], []
        while cur or stack:  # 迭代解法
            while cur: # cur 入栈, 并到达最左端的叶子节点。
                stack.append(cur)
                cur = cur.left
            tmp = stack.pop()
            res.append(tmp.val) # 出栈时再加入结果
            cur = tmp.right
        return res
145. 二叉树的后序遍历

题目:后序遍历

    def postorderTraversal(self, root: TreeNode) -> List[int]:
        if not root:
            return []
        res = list()
        self.postorder(root, res) # 递归解法
        return res

    def postorder(self, node: TreeNode, res: List[int]) -> None:
        if not node: 
            return
        self.postorder(node.left, res) # 左子树
        self.postorder(node.right, res)  # 右子树
        res.append(node.val)  # 当前
    def postorderTraversal(self, root: TreeNode) -> List[int]:
        if not root:
            return []
        cur, stack, res = root, [], []
        while cur or stack: 
            while cur: # 先到达最右端
                res.append(cur.val) # 
                stack.append(cur)
                cur = cur.right
            tmp = stack.pop()
            cur = tmp.left
        return res[::-1] # 反向输出
100. 相同的树

题目:相同的树

    def isSameTree(self, p: TreeNode, q: TreeNode) -> bool:
        if not p and not q: # p和q都是空
            return True
        elif not p or not q: # p和q有一个是空
            return False
        elif p.val != q.val: # p和q都不是空但是值不一样
            return False
        else:
            return self.isSameTree(p.left, q.left) and self.isSameTree(p.right, q.right)
101. 对称二叉树

题目: 对称二叉树

    def isSymmetric(self, root: TreeNode) -> bool:
        return self.check(root, root)

    def check(self, p: TreeNode, q: TreeNode) -> bool:
        if not p and not q: # 左右都为空
            return True
        elif not p or not q: # 左右有一个为空
            return False
        else: 
            return p.val == q.val and self.check(p.left, q.right) and self.check(p.right, q.left)
104. 二叉树的最大深度

题目: 二叉树的最大深度

    def maxDepth(self, root: TreeNode) -> int:
        if not root: 
            return 0
        return 1 + max(self.maxDepth(root.left), self.maxDepth(root.right)) # 递归解法
111. 二叉树的最小深度

题目:二叉树的最小深度

        if not root:
            return 0
        que = collections.deque([(root, 1)])
        while que:
            node, depth = que.popleft() # depth是用来记录深度的
            if not node.left and not node.right: # 只到某个节点没有左右子叶
                return depth
            if node.left:
                que.append((node.left, depth + 1))
            if node.right:
                que.append((node.right, depth + 1))
        return 0
108. 将有序数组转换为二叉搜索树

题目:将有序数组转换为二叉搜索树

    def sortedArrayToBST(self, nums: List[int]) -> TreeNode:
        def helper(left, right):
            if left > right:
                return None
            # 总是选择中间位置左边的数字作为根节点
            mid = (left + right) // 2
            root = TreeNode(nums[mid])
            root.left = helper(left, mid - 1)
            root.right = helper(mid + 1, right)
            return root
            
        return helper(0, len(nums) - 1)
110. 平衡二叉树

题目:平衡二叉树

    def isBalanced(self, root: TreeNode) -> bool:
        def height(root: TreeNode) -> int: # 第104题最大深度
            if not root:
                return 0
            return max(height(root.left), height(root.right)) + 1

        if not root:
            return True
        return abs(height(root.left) - height(root.right)) <= 1 and self.isBalanced(root.left) and self.isBalanced(root.right)
112. 路径总和

题目:路径总和

    def hasPathSum(self, root: TreeNode, sum: int) -> bool:
        if not root:
            return False
        if not root.left and not root.right:
            return sum == root.val
        # 考虑左右节点,sum与当前节点的值的差值作为函数输入
        return self.hasPathSum(root.left, sum - root.val) or self.hasPathSum(root.right, sum - root.val)
226. 翻转二叉树

题目:翻转二叉树
思考:如果当前遍历到的节点 root 的左右两棵子树都已经翻转,那么我们只需要交换两棵子树的位置,即可完成以root 为根节点的整棵子树的翻转。

    def invertTree(self, root: TreeNode) -> TreeNode:
        if not root:
            return root
        left = self.invertTree(root.left)
        right = self.invertTree(root.right)
        root.left, root.right = right, left
        return root
235. 二叉搜索树的最近公共祖先

题目:二叉搜索树的最近公共祖先

    def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
        if p.val < root.val and root.val > q.val: # 都在root的左子树里
            return self.lowestCommonAncestor(root.left, p, q)
        if p.val > root.val and root.val < q.val: # 都在root的右子树里
            return self.lowestCommonAncestor(root.right, p, q)
        return root
257. 二叉树的所有路径

题目:二叉树的所有路径

    def binaryTreePaths(self, root: TreeNode) -> List[str]:
        def construct_paths(root, path):
            if root:
                path += str(root.val)
                if not root.left and not root.right:  # 当前节点是叶子节点
                    paths.append(path)  # 把路径加入到答案中
                else:
                    path += '->'  # 当前节点不是叶子节点,继续递归遍历
                    construct_paths(root.left, path)
                    construct_paths(root.right, path)

        paths = []
        construct_paths(root, '')
        return paths
上一篇 下一篇

猜你喜欢

热点阅读