【LeetCode】1372 and 1342(后序遍历的适用场景)

后续遍历框架的适用场景

很简单的思路,如果当前节点要做的事情需要通过左右⼦树的计算结果推导出来,就要⽤到后序遍历。

1373. 二叉搜索子树的最大键值和

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

解法:DFS 后序遍历
同样,按照管理,我们需要明确针对树中的每个节点「要做什么」以及「什么时候做」。根据二叉搜索树(BST)相关性质,我们确定「要做什么」,内容如下:

  1. 判断左子树和右子树是否为二叉搜索树
  2. 判断当前节点值是否大于左子树的最大值
  3. 判断当前节点值是否小于右子树的最小值
  4. 求解以当前节点为根节点的子树键值和

根据以上三点,站在当前节点的视⻆,需要知道以下具体信息:

  1. 左右⼦树是否是 BST。
  2. 左⼦树的最⼤值和右⼦树的最⼩值。
  3. 左右⼦树的节点值之和。

由于需要传递的信息超过1个,因此我们可以使用一个长度为4的整形数组来存储每个子树的返回值。

「什么时候做」:由于相关操作需要在得到左右子树的返回值后计算,因此采用后序遍历框架。

# 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:
	# 全局变量用于存储最大键值和,初始化为0是为了针对题目中的示例3,即所有节点键值都为负数,返回0
    maxSum = 0
    def maxSumBST(self, root: Optional[TreeNode]) -> int:
        self.traverse(root)
        return self.maxSum

    def traverse(self, node):
        if not node:
            # 叶子节点可视为单独的二叉搜索树,其左右子树都为空,因此要将子树最大值设置为负无穷,最小值设置为最小值,保证以该叶子节点为根节点的子树最大值和最小值都是它本身,体现25、26行。
            return [1, float("-inf"), float("inf"), 0]

        # 是否BST,子树最大值,子树最小值,子树键值和
        left = self.traverse(node.left)
        right = self.traverse(node.right)

        # 判断以node为根节点子树是否为BST
        if left[0] == 1 and right[0] == 1 and node.val > left[1] and node.val < right[2]:
            sum_tree = left[3] + right[3] + node.val
            max_value = max(right[1], node.val)
            min_value = min(left[2], node.val)
            self.maxSum = max(self.maxSum, sum_tree)
            return [1, max_value, min_value, sum_tree]
        else:
        	# 非BST,后三个位置数值后续不会用到,因此可以任意初始化,这里统一设置为0
            return [0, 0, 0, 0]

1342. 将数字变为0的操作次数

在这里插入图片描述
解法:模拟
根据题意对相关操作进行模拟。

class Solution:
    def numberOfSteps(self, num: int) -> int:
        count = 0
        while num != 0:
            if num % 2 == 0:
                num //= 2
            else:
                num -= 1
            count += 1
        return count

参考文档

有关二叉搜索树(BST)的介绍

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值