leetcode task03 144.二叉树的前序遍历 0094. 二叉树的中序遍历 0145. 二叉树的后序遍历 102. 二叉树的层序遍历 105.从前序与中序遍历序列构造二叉树


一、树与二叉树的基本知识、二叉树的遍历

学习链接

二、0144.二叉树的前序遍历

题目:
给你二叉树的根节点 root ,返回它节点值的 前序 遍历。

示例:
输入:root = [1,null,2,3]
输出:[1,2,3]

在这里插入图片描述
思路1:
采用递归的方法来实现前序遍历。
先遍历根节点,在遍历左子节点,最后遍历右子节点

class Solution:
    def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        order = []
        def perorder(root):
            if not root:
                return
            order.append(root.val)
            perorder(root.left)
            perorder(root.right)

        perorder(root)
        return order

思路2:
采用迭代的方式来实现,即使用显示栈。

class Solution:
    def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        order = []
        stack = [root]

        while root and stack:
            node = stack.pop()
            order.append(node.val)

            if node.right:
                stack.append(node.right)
            if node.left:
                stack.append(node.left)
        
        return order

还有一种方法,通过morris遍历,可实现 O ( 1 ) O(1) O(1)的空间复杂度。

三、94. 二叉树的中序遍历

题目:
给定一个二叉树的根节点 root ,返回 它的 中序 遍历 。

示例:
输入:root = [1,null,2,3]
输出:[1,3,2]

思路1:
采用递归的方法进行求解:
先遍历左子树,再访问根节点,最后访问右子树。

class Solution:
    def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        order = []

        def inorder(root):
            if not root:
                return
            inorder(root.left)
            order.append(root.val)
            inorder(root.right)
        
        inorder(root)
        return order

思路2:
采用迭代的方法求解,同样使用显示栈。

class Solution:
    def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        if not root:
            return []
        
        order = []
        stack = []
        while stack or root:

            while root:
                stack.append(root)
                root = root.left
            
            node = stack.pop()
            order.append(node.val)
            root = node.right
        
        return order

四、0145. 二叉树的后序遍历

题目:
给你一棵二叉树的根节点 root ,返回其节点值的 后序遍历 。

示例:
输入:root = [1,null,2,3]
输出:[3,2,1]

思路1:
采用递归的方法求解。
先遍历左子树,再遍历右子树,最后访问根节点。

class Solution:
    def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        order = []

        def postorder(root):
            if not root:
                return
            
            postorder(root.left)
            postorder(root.right)
            order.append(root.val)
        
        postorder(root)
        return order

思路2:
采用迭代的方法,即显示栈实现。

class Solution:
    def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        order = []
        stack = []
        prev = None
        while root or stack:
            while root:
                stack.append(root)
                root = root.left
            
            node = stack.pop()
            if node.right == prev or not node.right:
                order.append(node.val)
                prev = node
                root = None
            else:
                stack.append(node)
                root = node.right
            
        return order


五、102. 二叉树的层序遍历

题目:
给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。
示例:
输入:root = [3,9,20,null,null,15,7]
输出:[[3],[9,20],[15,7]]

思路:
使用队列来模拟层序遍历。

class Solution:
    def levelOrder(self, root: TreeNode) -> List[List[int]]:
        if not root:
            return []
        queue = [root]
        order = []
        while queue:
            order1 = []
            size = len(queue)
            for _ in range(size):
                node = queue.pop(0)
                order1.append(node.val)
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)
            order.append(order1)
        return order

六、105.从前序与中序遍历序列构造二叉树

题目:
给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。

示例:
输入: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
输出: [3,9,20,null,null,15,7]

思路:
从前序遍历序列可以知道根节点,再根据中序遍历序列就可以知道左子序列和右子序列的集合。
采用递归实现即可。

class Solution:
    def buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode:
        def creatTree(preorder,inorder,n):
            if n == 0:
                return None
            k = 0
            while preorder[0] != inorder[k]:
                k += 1
            node = TreeNode(inorder[k])
            node.left = creatTree(preorder[1:k+1],inorder[0:k],k)
            node.right = creatTree(preorder[k+1:],inorder[k+1:],n-k-1)
            return node
        return creatTree(preorder,inorder,len(inorder))

七、106. 从中序与后序遍历序列构造二叉树

题目:
给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。

示例:
输入:inorder = [9,3,15,20,7], postorder = [9,15,7,20,3]
输出:[3,9,20,null,null,15,7]

思路:
从后序遍历序列的最后一个可以知道根节点,同理将该节点代入到中序遍历序列中进行查找,即可得到左子序列和右子序列。
采用递归实现即可。

class Solution:
    def buildTree(self, inorder: List[int], postorder: List[int]) -> TreeNode:
        def creatTree(inorder,postorder,n):
            if n == 0:
                return None
            k = 0
            while postorder[n-1] != inorder[k]:
                k += 1
            node = TreeNode(inorder[k])
            node.left = creatTree(inorder[0:k],postorder[0:k],k)
            node.right = creatTree(inorder[k+1:],postorder[k:n-1],n-1-k)
            return node
        return creatTree(inorder,postorder,len(inorder))

八、889. 根据前序和后序遍历构造二叉树

题目:
给定两个整数数组,preorder 和 postorder ,其中 preorder 是一个具有 无重复 值的二叉树的前序遍历,postorder 是同一棵树的后序遍历,重构并返回二叉树。
如果存在多个答案,您可以返回其中 任何 一个。

示例:
输入:preorder = [1,2,4,5,3,6,7], postorder = [4,5,2,6,7,3,1]
输出:[1,2,3,4,5,6,7]

在这里插入图片描述

思路:
前序遍历的顺序是:根节点-左子树-右子树;
后序遍历的顺序是:左子树-右子树-根节点。
因此,可以假设前序遍历的第二个元素为后序遍历中左子树遍历的最后一个节点,并区分左右子树序列。
分出左右子树序列后,就可以使用递归实现。

class Solution:
    def constructFromPrePost(self, preorder: List[int], postorder: List[int]) -> TreeNode:
        def creatTree(preorder,postorder,n):
            if n == 0:
                return None
            node = TreeNode(preorder[0])
            if n == 1:
                return node
            k = 0
            while preorder[1] != postorder[k]:
                k += 1
            node.left = creatTree(preorder[1:k+2],postorder[0:k+1],k+1)
            node.right = creatTree(preorder[k+2:],postorder[k+1:-1],n-k-2)
            return node
        return creatTree(preorder,postorder,len(preorder))

九、二叉搜索树

学习链接

二叉树ASL推导

十、700. 二叉搜索树中的搜索

题目:
给定二叉搜索树(BST)的根节点 root 和一个整数值 val。

你需要在 BST 中找到节点值等于 val 的节点。 返回以该节点为根的子树。 如果节点不存在,则返回 null 。

示例:
输入:root = [4,2,7,1,3], val = 2
输出:[2,1,3]

思路:
直接按二叉搜索树的规则搜索即可。

class Solution:
    def searchBST(self, root: TreeNode, val: int) -> TreeNode:
        if not root:
            return None
        while root:
            if root.val > val:
                root = root.left
            elif root.val < val:
                root = root.right
            else:
                return root
        return None

十一、701. 二叉搜索树中的插入操作

题目:
给定二叉搜索树(BST)的根节点 root 和要插入树中的值 value ,将值插入二叉搜索树。 返回插入后二叉搜索树的根节点。 输入数据 保证 ,新值和原始二叉搜索树中的任意节点值都不同。

注意,可能存在多种有效的插入方式,只要树在插入后仍保持为二叉搜索树即可。 你可以返回 任意有效的结果 。

示例:
输入:root = [4,2,7,1,3], val = 5
输出:[4,2,7,1,3,5]

思路:
先进行二叉搜索,当搜到对应位置时插入节点即可。

class Solution:
    def insertIntoBST(self, root: TreeNode, val: int) -> TreeNode:
        if not root:
            return TreeNode(val)
        cur = root
        while cur:
            if cur.val > val:
                if not cur.left:
                    cur.left = TreeNode(val)
                    break
                else:
                    cur = cur.left
            else:
                if not cur.right:
                    cur.right = TreeNode(val)
                    break
                else:
                    cur = cur.right
        return root
            

十二、450. 删除二叉搜索树中的节点

题目:
给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变。返回二叉搜索树(有可能被更新)的根节点的引用。

一般来说,删除节点可分为两个步骤:

首先找到需要删除的节点;
如果找到了,删除它。

示例:
输入:root = [5,3,6,2,4,null,7], key = 3
输出:[5,4,6,2,null,null,7]
解释:给定需要删除的节点值是 3,所以我们首先找到 3 这个节点,然后删除它。
一个正确的答案是 [5,4,6,2,null,null,7], 如下图所示。
另一个正确答案是 [5,2,6,null,4,null,7]。

思路:
先二分搜索,再删除。

class Solution:
    def deleteNode(self, root: Optional[TreeNode], key: int) -> Optional[TreeNode]:
        if not root:
            return root
        if root.val > key:
            root.left = self.deleteNode(root.left,key)
            return root
        elif root.val < key:
            root.right = self.deleteNode(root.right,key)
            return root
        else:
            if not root.left:
                return root.right
            elif not root.right:
                return root.left
            else:
                cur = root.right
                while cur.left:
                    cur = cur.left
                cur.left = root.left
                return root.right

十三、98. 验证二叉搜索树

题目:
给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。

有效 二叉搜索树定义如下:

节点的左子树只包含 小于 当前节点的数。
节点的右子树只包含 大于 当前节点的数。
所有左子树和右子树自身必须也是二叉搜索树。

示例:

输入:root = [2,1,3]
输出:true

思路:
递归求解,不断判断左右子树是否也是一个二叉搜索树。

class Solution:
    def isValidBST(self, root: Optional[TreeNode]) -> bool:
        def helper(root,min_v,max_v):
            if not root:
                return True
            if root.val<=min_v or root.val>=max_v:
                return False
            return helper(root.left,min_v,root.val) and helper(root.right,root.val,max_v)
        return helper(root,float('-inf'),float('inf'))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值