leetcode—hot100-树1

一.二叉树的遍历

1.二叉树中序遍历

a.递归写法

b.迭代

递归写法很简单,迭代法用到栈stack。

思路是:迭代法,把root放到一个stack里,利用栈后进先出的性质,在迭代中令root=root.left,到了底部之后,从栈中弹出根节点,令root=root.right,达到遍历[左,跟,右]的目的。

2.二叉树的前序遍历

迭代法思路:建立一个栈stack,先root.right,再root.left,弹出的时候就先弹出left,再right.

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        def dfs(root):
            if root:
                res.append(root.val)
                dfs(root.left)
                dfs(root.right)
            else:
                return 
        
        res=[]
        dfs(root)
        return res
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        # 前序遍历: 根,左,右
        # 用一个stack来记录顺序性,其实递归也是有顺序性的(运行到最后一步,再往前走),用stack来代替递归
        if not root:
            return []
        stack = []
        stack.append(root)
        res = []
        while stack:
            node = stack.pop()
            res.append(node.val)
            if node.right:
                stack.append(node.right)
            if node.left:
                stack.append(node.left)
        return res

3.二叉树的后序遍历

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def postorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        #左 右 根
        #前序,根,左,右。
        #把前序变成 根,右,左,然后取反
        stack=[root]
        res=[]
        while stack:
            node=stack.pop()
            if node:
                res.append(node.val)
                stack.append(node.left)
                stack.append(node.right)
        return res[::-1]

4.二叉树的层序遍历

二.重建二叉树

1.根据前序遍历和中序遍历构建二叉树

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

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution(object):
    def buildTree(self, inorder, postorder):
        """
        :type inorder: List[int]
        :type postorder: List[int]
        :rtype: TreeNode
        """
        #后序:[左,右,跟]
        #中序:[左,跟,右]
        if not postorder:
            return None
        root=TreeNode(postorder[-1])
        inorder_index=inorder.index(root.val)
        root.left=self.buildTree(inorder[:inorder_index],postorder[:inorder_index])
        root.right=self.buildTree(inorder[inorder_index+1:],postorder[inorder_index:len(postorder)-1])
        return root

三.二叉树的序列化

东哥手把手带你刷二叉树(序列化篇)

可以用前序遍历,后序遍历,层序遍历。中序遍历不行,因为找不到根节点。

前序遍历写起来比较方便, 根左右的顺序,列表第一个就是根节点。

297. 二叉树的序列化与反序列化

 

前序遍历1

思路:前序遍历,遇到叶子节点,返回"#"

二叉树的序列化:把二叉树的节点值用字符串来表示。

二叉树的反序列化:把字符串表示的二叉树节点值,构造成二叉树。

前序遍历2

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Codec:
    def serialize(self, root):
        """Encodes a tree to a single string.
        
        :type root: TreeNode
        :rtype: str
        """
        #先试一下前序遍历,根,左,右。这样在反序列化的时候,容易找根节点
        res=[]
        stack=[]
        stack.append(root)
        while stack:
            node=stack.pop()
            if not node:
                break
            if node=="null":
                res.append("null")
                continue
            if node!="null":
                res.append(str(node.val))
            if node.right:
                stack.append(node.right)
            else:
                stack.append("null")
            if node.left:
                stack.append(node.left)
            else:
                stack.append("null")
        print(res)
        return ','.join(res)
        
    def deserialize(self, data):
        """Decodes your encoded data to tree.
        
        :type data: str
        :rtype: TreeNode
        """
        #root = [1,2,3,null,null,4,5]
        #序列化。[1,2,null,null,3,4,null,null,5,null,null]
        #从根节点开始
        if len(data)==0:
            return 
        data_list=data.split(",")
        print(data_list)
        def deserialize2(data):
            root_val=data_list.pop(0)
            if root_val!="null":
                root=TreeNode(int(root_val))
                root.left=deserialize2(data)
                root.right=deserialize2(data)
                return root
        return deserialize2(data)
       
# Your Codec object will be instantiated and called as such:
# ser = Codec()
# deser = Codec()
# ans = deser.deserialize(ser.serialize(root))

层序遍历

428. 序列化和反序列化 N 叉树

前序遍历,并记录child数量

"""
# Definition for a Node.
class Node(object):
    def __init__(self, val=None, children=None):
        self.val = val
        self.children = children
"""

class Codec:
    def serialize(self, root: 'Node') -> str:
        """Encodes a tree to a single string.
        
        :type root: Node
        :rtype: str
        """
        if root == None:
            return "#"
        data = ""
        data += str(root.val) + '-' + str(len(root.children))
        for child in root.children:
            data += '-' + self.serialize(child)
        return data        
	
    def deserialize(self, data: str) -> 'Node':
        """Decodes your encoded data to tree.
        
        :type data: str
        :rtype: Node
        """
        if data == "#":
            return None
        data = data.split('-')
        return self.dfs(data)

    def dfs(self, data: List[str]) -> 'Node':
        #建root结点
        val = int(data.pop(0))
        root = Node(val)
        root.children = []
        #递归儿子们
        size = int(data.pop(0))
        for _ in range(size):
            root.children.append(self.dfs(data))
        return root
        

# Your Codec object will be instantiated and called as such:
# codec = Codec()
# codec.deserialize(codec.serialize(root))

作者:code_learner
链接:https://leetcode-cn.com/problems/serialize-and-deserialize-n-ary-tree/solution/cpython3-1dfs-2bfs-by-hanxin_hanxin-606j/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

449. 序列化和反序列化二叉搜索树

前序遍历

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

#左 < 根 < 右。根,左,右的形式输入的,前序遍历,与一般前序遍历不同的是要存null节点,遍于反序列化找根
class Codec:
    def serialize(self, root: TreeNode) -> str:
        """Encodes a tree to a single string.
        """
        res = []
        def dfs(root):
            if not root:
                res.append("null")
            else:
                res.append(str(root.val))
                dfs(root.left)
                dfs(root.right)
        dfs(root)
        return "#".join(res)

    def deserialize(self, data: str) -> TreeNode:
        """Decodes your encoded data to tree.
        """
        if len(data)==0:
            return
        alist = data.split("#")
        def dfs(alist):
            root_val = alist.pop(0)
            if root_val != "null":
                root = TreeNode(root_val)
                root.left = dfs(alist)
                root.right = dfs(alist)
                return root
        return dfs(alist)

二叉搜索树的性质,前序+中序构造二叉树

class Codec:
    def serialize(self, root):
        def preorder(root):
            out = []
            if root:
                out += [str(root.val)]
                out += preorder(root.left)
                out += preorder(root.right)
            return out
        return ','.join(preorder(root))
        
    def deserialize(self, data):
        if not data:
            return None
        def buildTree(pre_o, in_o):
            if not pre_o:
                return None
            mid = pre_o[0]
            i = in_o.index(mid)
            root = TreeNode(mid)
            root.left = buildTree(pre_o[1:i + 1], in_o[:i])
            root.right = buildTree(pre_o[i + 1:], in_o[i + 1:])
            return root
        pre_o = list(map(int, data.split(',')))
        in_o = sorted(pre_o)
        return buildTree(pre_o, in_o)

四.二叉树的深度/平衡二叉树

二叉树的深度

递归写法。左边的深度,右边的深度,取最大值。

平衡二叉树

平衡二叉树,任意节点的子树的高度差都小于等于1。在判断完当前节点是否为平衡二叉树的之后,还要判断他的左右子树实不是平衡二叉树

五.二叉搜索树

230 二叉搜索树中第k小元素

中序遍历

96. 不同的二叉搜索树

 手把手带你刷通二叉搜索树(第三期)

深搜

class Solution:
    def numTrees(self, n: int) -> int:
        #左 < 根 < 右
        #递归寻找根节点,乘法原理.左子树小于根节点,右子树大于根节点
        @lru_cache(None)
        def dfs(left,right):
            if left > right:
                return 1
            #以i为根节点
            cur_res = 0
            for i in range(left,right+1):
                left_count = dfs(left,i-1)
                right_count = dfs(i+1,right)
                cur_res += left_count * right_count
            return cur_res
        return dfs(1,n)

97. 不同的二叉搜索树2

递归

class Solution:
    def generateTrees(self, n: int) -> List[TreeNode]:
        def generateTrees(start, end):
            if start > end:
                return [None,]
            
            allTrees = []
            for i in range(start, end + 1):  # 枚举可行根节点
                # 获得所有可行的左子树集合
                leftTrees = generateTrees(start, i - 1)
                
                # 获得所有可行的右子树集合
                rightTrees = generateTrees(i + 1, end)
                
                # 从左子树集合中选出一棵左子树,从右子树集合中选出一棵右子树,拼接到根节点上
                for l in leftTrees:
                    for r in rightTrees:
                        currTree = TreeNode(i)
                        currTree.left = l
                        currTree.right = r
                        allTrees.append(currTree)
            
            return allTrees
        
        return generateTrees(1, n) if n else []

作者:LeetCode-Solution
链接:https://leetcode.cn/problems/unique-binary-search-trees-ii/solution/bu-tong-de-er-cha-sou-suo-shu-ii-by-leetcode-solut/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

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

 利用二叉搜索树的性质,递归

六.二叉树的镜像/对称二叉树

二叉树的镜像

思路:反转左右子树,递归的对左右子树反转。

对称二叉树

思路:不能用镜像二叉树来判断。因为镜像之后,root就变成他的镜像树了,一直是true。

正确的思路是:判断左右子树是否相等,递归的进行。

翻转二叉树

leetcode-树-v2_MaYingColdPlay的博客-CSDN博客

七.二叉树的最近公共祖先

python - 二叉树的最近公共祖先_hotpotbo的博客-CSDN博客_python 二叉树最近公共祖先

剑指offer-leetcode-最大最小问题-思路篇_MaYingColdPlay的博客-CSDN博客

八.trie树

leetcode-数据结构类型的题_MaYingColdPlay的博客-CSDN博客

力扣208

九.二叉树展开为链表

LeetCode 114.二叉树展开为链表(Python实现)_ChungChinKei' blog-CSDN博客

十.树的子结构

366 寻找二叉树的叶子节点

[leetcode] 366. Find Leaves of Binary Tree @ python_tmfighting的博客-CSDN博客

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值