数据结构与算法——Java实现 53.力扣938题——二叉搜索树的范围和

生命的意义

在于活出自我

而不是成为别人眼中的你

------ 24.11.3

938. 二叉搜索树的范围和

给定二叉搜索树的根结点 root,返回值位于范围 [low, high] 之间的所有结点的值的和。

示例 1:

复制代码
输入:root = [10,5,15,3,7,null,18], low = 7, high = 15
输出:32

示例 2:

复制代码
输入:root = [10,5,15,3,7,13,18,1,null,6], low = 6, high = 10
输出:23

提示:

  • 树中节点数目在范围 [1, 2 * 104]
  • 1 <= Node.val <= 105
  • 1 <= low <= high <= 105
  • 所有 Node.val 互不相同

方法1 中序遍历判断范围

思路

由题目给出的输入序列可以看出,输入序列按照二叉树的层次遍历顺序进行排序

我们按照中序遍历(左 - 根 - 右)的顺序排列给出的节点,遍历树节点,如果树节点在此范围内,则将该节点的值加入总和中,若不在该范围内,则跳过该节点,观察下一个节点,直到遍历完所有节点为止

返回总和

java 复制代码
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public int rangeSumBST(TreeNode node,int low,int high){
        TreeNode p = node;
        LinkedList<TreeNode> stack = new LinkedList<>();
        int sum = 0;
        while(p != null || !stack.isEmpty()){
            if (p != null || !stack.isEmpty()){
                if (p != null){
                    stack.push(p);
                    // 左
                    p = p.left;
                }else {
                    TreeNode pop = stack.pop();
                    // 处理值
                    if (pop.val >= low && pop.val <= high){
                        sum += pop.val;
                    }
                    // 右
                    p = pop.right;
                }
            }
        }
        return sum;
    }
}

方法2 中序遍历剪枝优化

由于二叉搜索树的特性(左 < 根 < 右),当我们遍历到某一结点时发现该节点不在范围内,则其左子树/右子树可以直接进行剪枝操作

java 复制代码
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public int rangeSumBST(TreeNode node,int low,int high){
        TreeNode p = node;
        LinkedList<TreeNode> stack = new LinkedList<>();
        int sum = 0;
        while(p != null || !stack.isEmpty()){
            if (p != null || !stack.isEmpty()){
                if (p != null){
                    stack.push(p);
                    // 左
                    p = p.left;
                }else {
                    TreeNode pop = stack.pop();
                    // 处理值
                    if (pop.val > high){
                        break;
                    }
                    if (pop.val >= low){
                        sum += pop.val;
                    }
                    // 右
                    p = pop.right;
                }
            }
        }
        return sum;
    }
}

方法3 上下限递归剪枝优化

思路

从根节点开始进行递归,对于每个节点进行判断,若它的val值大于要求的范围,则将其右子树跳过不用遍历判断,若其val值小于要求的范围,则将其左子树跳过不用遍历判断,如此可大大提高程序的效率 (通过范围上下限判定进行剪枝操作)

java 复制代码
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public int rangeSumBST(TreeNode node,int low,int high){
        if (node == null){
            return 0;
        }
        if (node.val < low){
            // 将节点的左子树省去
            return rangeSumBST(node.right,low,high);
        }
        if (node.val > high){
            // 将节点的右子树省去
            return rangeSumBST(node.left,low,high);
        }

        return node.val + rangeSumBST(node.left,low,high) + rangeSumBST(node.right,low,high);
    }
}
相关推荐
橙橙子230几秒前
c++柔性数组、友元、类模版
开发语言·c++·柔性数组
程序媛学姐8 分钟前
SpringKafka错误处理:重试机制与死信队列
java·开发语言·spring·kafka
2401_8401922716 分钟前
如何学习一门计算机技术
开发语言·git·python·devops
向阳25625 分钟前
SpringBoot+vue前后端分离整合sa-token(无cookie登录态 & 详细的登录流程)
java·vue.js·spring boot·后端·sa-token·springboot·登录流程
巷北夜未央30 分钟前
Python每日一题(14)
开发语言·python·算法
爱爬山的老虎33 分钟前
【面试经典150题】LeetCode121·买卖股票最佳时机
数据结构·算法·leetcode·面试·职场和发展
XiaoLeisj42 分钟前
【MyBatis】深入解析 MyBatis XML 开发:增删改查操作和方法命名规范、@Param 重命名参数、XML 返回自增主键方法
xml·java·数据库·spring boot·sql·intellij-idea·mybatis
风象南42 分钟前
SpringBoot实现数据库读写分离的3种方案
java·spring boot·后端
振鹏Dong1 小时前
策略模式——本质是通过Context类来作为中心控制单元,对不同的策略进行调度分配。
java·策略模式
ChinaRainbowSea1 小时前
3. RabbitMQ 的(Hello World) 和 RabbitMQ 的(Work Queues)工作队列
java·分布式·后端·rabbitmq·ruby·java-rabbitmq