16. 二叉搜索树的范围和|Java 刷题打卡

370 阅读2分钟

本文正在参加「Java主题月 - Java 刷题打卡」,详情查看<活动链接>

【Java 刷题打卡】 刷题比玩游戏好多了,成就感越来越强,每天坚持刷几道题,每天锻炼30分钟,等8块腹肌,等大厂offer.

😄

 \color{red}{~}

那就干吧! 这个专栏都是刷的题目都是关于二叉树的,我会由浅入深、循序渐进,刷题就是这样需要连续不断的记忆--艾宾浩斯记忆法2121112。二叉树的内容不多,但是都是每个程序员必备的,对了解红黑树、B+树、LSM树都非常有帮助等等

WAL+LSM-tree实现的leveldb和rocksdb

B+ 树的mysql

(HBASE) - LSM-tree的架构把random write转成sequential write,多层的compaction和lookup,存在写放大和读放大

TokuDB索引结构--Fractal Tree

还有更多,值得咱们发掘。

leecode 938. 二叉搜索树的范围和

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

图片.png

输入:root = [10,5,15,3,7,null,18], low = 7, high = 15

输出:32

图片.png

输入: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 互不相同


二叉搜索树具有以下性质:每个节点中的值必须大于(或等于)其左侧子树中的任何值,但小于(或等于)其右侧子树中的任何值。

参考代码

定义一颗树

class TreeNode {
    int val;          // 头结点
    TreeNode left;    // 左子树
    TreeNode right;   // 右子树

    TreeNode(int x) {
        val = x;
    }
}


// 测试方法
 public static void main(String[] args) {
        TreeNode treeNode = new TreeNode(1);
        treeNode.left = new TreeNode(2);
        treeNode.right = new TreeNode(3);
        System.out.println("xxxx结果 = " + preorderTraversal(treeNode));
}        

按深度优先搜索的顺序计算范围和。记当前子树根节点为 root,分以下四种情况讨论: 图片.png 1.root 节点为空

返回 0。

2.root 节点的值大于high,例如[3,7]

由于二叉搜索树右子树上所有节点的值均大于根节点的值,即均大于 high,故无需考虑右子树,返回左子树的范围和。

3.root 节点的值小于 low , 例如[15,18]

由于二叉搜索树左子树上所有节点的值均小于根节点的值,即均小于 low,故无需考虑左子树,返回右子树的范围和。

4.root 节点的值在 [low,high] 范围内,例如 [7,15]

此时应返回 root 节点的值、左子树的范围和、右子树的范围和这三者之和。

JAVA 递归

// 
class Solution {
    public int rangeSumBST(TreeNode root, int low, int high) {
        if (root == null) {
            return 0;
        }
        if (root.val > high) {
            return rangeSumBST(root.left, low, high);
        }
        if (root.val < low) {
            return rangeSumBST(root.right, low, high);
        }
        return root.val + rangeSumBST(root.left, low, high) + rangeSumBST(root.right, low, high);
    }
}

JAVA 迭代 队列:先进先出

使用广度优先搜索的方法,用一个队列 q 存储需要计算的节点。每次取出队首节点时,若节点为空则跳过该节点,否则按方法一中给出的大小关系来决定加入队列的子节点。



class Solution {
    public int rangeSumBST(TreeNode root, int low, int high) {
        int sum = 0;
        Queue<TreeNode> q = new LinkedList<TreeNode>();
        q.offer(root);      // 整棵树怼进去
        while (!q.isEmpty()) {
            TreeNode node = q.poll(); // 整棵树取出来
            if (node == null) {
                continue;
            }
            if (node.val > high) {   // 根节点大于最大值,就在左子树
                q.offer(node.left);  //  将左子树添加道队列
            } else if (node.val < low) {  // 小于,就在右子树
                q.offer(node.right);
            } else {
                sum += node.val;      // 在中间,先添加根节点到累加和
                q.offer(node.left);   // 将左子树怼进队列,5,3,7 
                q.offer(node.right);  // 将右子树怼进队列
            }
        }
        return sum;
    }
}




真心感谢帅逼靓女们能看到这里,如果这个文章写得还不错,觉得有点东西的话

求点赞👍 求关注❤️ 求分享👥 对8块腹肌的我来说真的 非常有用!!!

如果本篇博客有任何错误,请批评指教,不胜感激 !❤️❤️❤️❤️