leetcode二叉树

这篇博客介绍了二叉树的特性和在LeetCode中的一些典型问题,如二叉搜索树的最近公共祖先,将二叉树转换为累加树,序列化和反序列化二叉树,以及验证二叉树的正确性。通过遍历、递归和并查集等方法解决这些问题,展示了二叉树在算法中的应用。
摘要由CSDN通过智能技术生成

1.二叉树的特点

左<根<右

2. leetcode235 二叉搜索树的最近公共祖先

在这里插入图片描述
在这里插入图片描述

2.1 遍历二叉树查找

这个方法没有重复利用平衡二叉树的特点: 左<根<右

  1. 搜索到对应的p和q 所在位置,并记录先前的父节点
  2. 找到的最后一个共有的节点,也就是最近公共点
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
        stack = [([root],root)]
        pre_stack = []
        while stack:
            p_stack, node = stack.pop(-1)
            if node.val == p.val or node.val == q.val:
                pre_stack.append(p_stack)
            if len(pre_stack) ==2:
                break    
            if node.left:
                stack.append((p_stack + [node.left],node.left))
            if node.right:
                stack.append((p_stack+ [node.right],node.right))      
        i = 0        
        while i<min(len(pre_stack[0]), len(pre_stack[1])):
            if pre_stack[0][i]!=pre_stack[1][i]:
                break
            res = pre_stack[0][i]     
            i+=1             
        return res       



2.2 结合二叉搜索树的特性

左节点<根<右节点

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

class Solution:
    def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
        while (root.val-p.val)*(root.val-q.val)>0:
            if p.val< root.val:
                root = root.left
            else:
                root = root.right    
        return root      



# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
        stack = [root]
        while stack:
            node = stack.pop(-1)
            if (node.val - p.val)*(node.val-q.val)>0:
                if p.val < node.val:
                    stack.append(node.left)
                else:
                    stack.append(node.right)    
            else:
                res = node
                break        
           
        return res 

2.3 递归解法

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

class Solution:
    def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
        if (root.val-p.val)*(root.val-q.val)<=0:
            return root   
        if p.val < root.val:
            return self.lowestCommonAncestor(root.left, p, q)   
        else:
            return self.lowestCommonAncestor(root.right, p, q)   

3. leetcode538 把二叉树转为累加树

在这里插入图片描述
在这里插入图片描述
按照 右 -->根–>左的顺序遍历二叉树,并且修改节点的value

# 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 convertBST(self, root: TreeNode) -> TreeNode:
        if not root:
            return root
        stack = [(0, root)]
        res = 0
        while stack:
            flag, node = stack.pop(-1)
            if flag or (not node.left and not node.right):
                node.val += res
                res = node.val 
                continue
            if node.left:
                stack.append((0,node.left))
            stack.append((1,node))    
            if node.right:
                stack.append((0,node.right))
        return root

4. leetcode449 序列化和反序列二叉树

在这里插入图片描述
解决方法:

  1. 按层次序列化,遇到空节点时用-1表示
  2. 根据层次反序列化
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Codec:
    def serialize(self, root: TreeNode) -> str:
        """Encodes a tree to a single string.
        """
        if not root:
            return ""
        res = []
        stack = [root]
        res.append(str(root.val))
        while stack:
            node = stack.pop(-1)
            if node.left:
                res.append(str(node.left.val))
                stack.append(node.left) 
            else:
                res.append(str(-1))    
            
            if node.right:
                res.append(str(node.right.val))
                stack.append(node.right)
            else:
                res.append(str(-1))               
        return ",".join(res)           

    def deserialize(self, data: str) -> TreeNode:
        """Decodes your encoded data to tree.
        """
        if not data:
            return []
        res = list(map(int, data.split(",")))
        root = TreeNode(res[0])
        stack = [root]
        i=1
        while stack and i < len(res):
            node = stack.pop(-1)
            if res[i] !=-1:
                node.left = TreeNode(res[i])
                stack.append(node.left)
            if res[i+1] != -1:
                node.right = TreeNode(res[i+1])
                stack.append(node.right)
            i+=2      
        return root

5. leetcode1361 验证二叉树

用并查集的方法:
需注意一边merge,一边判断是否二叉树

  1. 若在操作前,子节点的父,不是本身,则该节点已是别的节点的子节点,则这不是二叉树;
  2. 若新的父节点的父和子节点的 父相同,(有环),则不是二叉树;
  3. 若最终的连通图个数>1 ,则不是二叉树。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

class Solution:
    def validateBinaryTreeNodes(self, n: int, leftChild: List[int], rightChild: List[int]) -> bool:
        isVisit = [0]*n
        cnt = n
        f = [i for i in range(n)] 
        
        def getFather(x):
            if f[x] == x:
                return x
                f[x] = getFather(f[x])
            return f[x] 
        def union(x, y):
            nonlocal cnt
            if y == -1:  # child 为空直接返回true
                return True
            if f[y] != y:  # child 已为别人的子节点,返回false
                return False
            fx = getFather(x)
            fy = getFather(y)
            if fx==fy:   # 父和子的根节点一样, false
                return False
            else:
                cnt -= 1     # 合并一次,连通图个数减一
                f[y] = fx   
                return True
                
        res = []
        childs = []
        flag = True 
        for i in range(n):
            if rightChild[i]==leftChild[i]  and leftChild[i]!= -1:
                return False
            if not union(i, leftChild[i]) or not union(i, rightChild[i]):
                return False
        if cnt == 1:
            return True
        else:
            return False            

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值