leetcode树之二叉树的操作

257、二叉树的所有路径

给你一个二叉树的根节点 root ,按 任意顺序 ,返回所有从根节点到叶子节点的路径。

叶子节点 是指没有子节点的节点。

示例1:

输入:root = [1,2,3,null,5]
输出:["1->2->5","1->3"]

示例2:

输入:root = [1]
输出:["1"]

思路:

递归拼接所有路径

class Solution:
    def binaryTreePaths(self, root: Optional[TreeNode]) -> List[str]:
        if not root: return []
        # 如果没有子节点,返回结点字符串的数组
        if not root.left and not root.right:
            return [str(root.val)]
        left = self.binaryTreePaths(root.left)
        right = self.binaryTreePaths(root.right)
        ans = left + right
        # 进行左右子树路径字符串的拼接
        return [f"{root.val}->{item}" for item in ans]
404、左叶子之和

给定二叉树的根节点 root ,返回所有左叶子之和。

示例1:

输入: root = [3,9,20,null,null,15,7] 
输出: 24 
解释: 在这个二叉树中,有两个左叶子,分别是 9 和 15,所以返回 24

示例2:

输入: root = [1]
输出: 0

思路:

深度优先遍历,在遍历左子节点的过程中,判断是否是叶子结点,如果是则累计加和

class Solution:
    def sumOfLeftLeaves(self, root: TreeNode) -> int:
        if not root: return 0
        stack = []
        cur = root
        ans = 0
        while cur or stack:
            while cur:
                stack.append(cur)
                cur = cur.left
                # 如果当前结点是叶子节点,说明该叶子节点是满足条件的左叶子节点,累加和即可
                if cur and not cur.left and not cur.right::
                    ans += cur.val
            cur = stack.pop()
            cur = cur.right
        return ans
671、二叉树中第二小的节点

给定一个非空特殊的二叉树,每个节点都是正数,并且每个节点的子节点数量只能为 2 或 0。如果一个节点有两个子节点的话,那么该节点的值等于两个子节点中较小的一个。

更正式地说,即 root.val = min(root.left.val, root.right.val) 总成立。

给出这样的一个二叉树,你需要输出所有节点中的 第二小的值 。

如果第二小的值不存在的话,输出 -1 。

示例1:

输入:root = [2,2,5,null,null,5,7]
输出:5
解释:最小的值是 2 ,第二小的值是 5 。

示例2:

输入:root = [2,2,2]
输出:-1
解释:最小的值是 2, 但是不存在第二小的值。

思路:

由于节点值等于左右子节点中较小的一个,那么可以得出结论,根节点是整棵树中最小的节点,那么第二小的节点是严格大于根节点值的节点,可以递归遍历,找到比根节点大的值。

class Solution:
    def findSecondMinimumValue(self, root: TreeNode) -> int:
        self.ans, root_val = -1, root.val
        def dfs(root):
            if not root: return
            # 如果ans有值,并且结点值大于ans的值,说明该子树的所有值都大于等于ans,提前跳出即可
            if self.ans != -1 and root.val >= self.ans:
                return
            # 如果结点值大于根节点的值,更新ans的值
            if root.val > root_val:
                ans = root.val
            dfs(root.left)
            dfs(root.right)
        dfs(root)
        return self.ans
993、二叉树的堂兄弟节点

在二叉树中,根节点位于深度 0 处,每个深度为 k 的节点的子节点位于深度 k+1 处。

如果二叉树的两个节点深度相同,但 父节点不同 ,则它们是一对堂兄弟节点。

我们给出了具有唯一值的二叉树的根节点 root ,以及树中两个不同节点的值 x 和 y 。

只有与值 x 和 y 对应的节点是堂兄弟节点时,才返回 true 。否则,返回 false。

示例1:

输入:root = [1,2,3,4], x = 4, y = 3
输出:false

示例2:

输入:root = [1,2,3,null,4,null,5], x = 5, y = 4
输出:true

示例3:

输入:root = [1,2,3,null,4], x = 2, y = 3
输出:false

思路:

满足堂兄弟节点的条件为,两个结点在同一层,两个结点的父节点不一样。

这样考虑下来,就很自然的想到使用层序遍历,由于二叉树是具有唯一值的,也就是不会出现两个同样值的结点。找到子节点之后,如果发现父节点不一致,那么直接返回即可

class Solution:
    def isCousins(self, root: TreeNode, x: int, y: int) -> bool:
        queue = [root]
        while queue:
            n = len(queue)
            parent = None
            # 层序遍历
            for i in range(n):
                cur = queue.pop(0)
                # 遍历每个节点左右子节点,找到指定的结点
                for node in [cur.left, cur.right]:
                    if not node: continue
                    queue.append(node)
                    if node.val != x and node.val != y: continue
                    # 如果找到结点,判断父节点是否存在,如果存在说明之前已经找到一个结点,
                    # 那么判断一下父节点和当前结点的父节点是否一致,这里直接返回即可,因为二叉树是具有唯一值的
                    # 否则给父节点赋值
                    if parent: return cur != parent
                    else: parent = cur
        return False
1022、从根到叶的二进制之和

给出一棵二叉树,其上每个结点的值都是 0 或 1 。每一条从根到叶的路径都代表一个从最高有效位开始的二进制数。例如,如果路径为 0 -> 1 -> 1 -> 0 -> 1,那么它表示二进制数 01101,也就是 13 。

对树上的每一片叶子,我们都要找出从根到该叶子的路径所表示的数字。

返回这些数字之和。题目数据保证答案是一个 32 位 整数。

示例1:

输入:root = [1,0,1,0,1,0,1]
输出:22
解释:(100) + (101) + (110) + (111) = 4 + 5 + 6 + 7 = 22

示例2:

输入:root = [0]
输出:0

示例3:

输入:root = [1]
输出:1

示例4:

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

思路:

先递归找到所有从根到叶的路径并拼接成二进制,然后转化为10进制进行求和

class Solution:
    def sumRootToLeaf(self, root: Optional[TreeNode]) -> int:
        def dfs(root):
            if not root: return []
            if not root.left and not root.right: return [str(root.val)]
            left = dfs(root.left)
            right = dfs(root.right)
            ans = left + right
            # 进行路径拼接
            return [f"{root.val}{val}"for val in ans]

        ans = dfs(root)
        # int第二个参数是当前传入的数据是以什么进制传入的,这里传2指的是以二进制传入
        return sum([int(item, 2) for item in ans])
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

溪语流沙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值