news 2026/4/16 14:00:44

算法题 二叉搜索树的范围和

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
算法题 二叉搜索树的范围和

938. 二叉搜索树的范围和

问题描述

给定二叉搜索树的根节点root,以及两个整数lowhigh,返回所有节点值在范围[low, high]内的节点值之和。

二叉搜索树

  • 对于任意节点,左子树的所有节点值都小于该节点值
  • 右子树的所有节点值都大于该节点值
  • 左右子树也都是二叉搜索树

示例

输入: root = [10,5,15,3,7,null,18], low = 7, high = 15 输出: 32 解释: 节点值在[7,15]范围内的有: 7, 10, 15,和为32。 输入: root = [10,5,15,3,7,13,18,1,null,6], low = 6, high = 10 输出: 23 解释: 节点值在[6,10]范围内的有: 6, 7, 10,和为23。

算法思路

核心思想

  • 如果当前节点值小于low,则左子树所有节点都不在范围内,只需遍历右子树
  • 如果当前节点值大于high,则右子树所有节点都不在范围内,只需遍历左子树
  • 如果当前节点值在范围内,则累加该节点值,并递归遍历左右子树

代码实现

方法一:递归

/** * 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; * } * } */classSolution{/** * 计算二叉搜索树中范围[low, high]内节点值的和 * * @param root 二叉搜索树的根节点 * @param low 范围下界(包含) * @param high 范围上界(包含) * @return 范围内节点值的和 */publicintrangeSumBST(TreeNoderoot,intlow,inthigh){// 基础情况:空节点if(root==null){return0;}// 当前节点值小于low,左子树都不在范围内,只遍历右子树if(root.val<low){returnrangeSumBST(root.right,low,high);}// 当前节点值大于high,右子树都不在范围内,只遍历左子树if(root.val>high){returnrangeSumBST(root.left,low,high);}// 当前节点值在范围内,累加当前值 + 左右子树的结果returnroot.val+rangeSumBST(root.left,low,high)+rangeSumBST(root.right,low,high);}}

方法二:迭代

classSolution{/** * 使用显式栈避免递归 */publicintrangeSumBST(TreeNoderoot,intlow,inthigh){if(root==null){return0;}Stack<TreeNode>stack=newStack<>();stack.push(root);intsum=0;while(!stack.isEmpty()){TreeNodecurrent=stack.pop();if(current==null){continue;}// 当前节点值在范围内if(current.val>=low&&current.val<=high){sum+=current.val;// 左右子树都可能有符合条件的节点stack.push(current.left);stack.push(current.right);}// 当前节点值小于low,只考虑右子树elseif(current.val<low){stack.push(current.right);}// 当前节点值大于high,只考虑左子树else{stack.push(current.left);}}returnsum;}}

方法三:BFS层序遍历

classSolution{/** * 使用队列进行层序遍历 */publicintrangeSumBST(TreeNoderoot,intlow,inthigh){if(root==null){return0;}Queue<TreeNode>queue=newLinkedList<>();queue.offer(root);intsum=0;while(!queue.isEmpty()){TreeNodecurrent=queue.poll();if(current.val>=low&&current.val<=high){sum+=current.val;if(current.left!=null)queue.offer(current.left);if(current.right!=null)queue.offer(current.right);}elseif(current.val<low){if(current.right!=null)queue.offer(current.right);}else{// current.val > highif(current.left!=null)queue.offer(current.left);}}returnsum;}}

方法四:无剪枝的递归

classSolution{/** * 简单递归 */publicintrangeSumBST(TreeNoderoot,intlow,inthigh){if(root==null){return0;}intsum=0;if(root.val>=low&&root.val<=high){sum+=root.val;}// 无论当前值如何,都要遍历左右子树sum+=rangeSumBST(root.left,low,high);sum+=rangeSumBST(root.right,low,high);returnsum;}}

算法分析

方法时间复杂度空间复杂度
递归O(n) 最坏, O(log n) 平均O(h)
迭代O(n) 最坏, O(log n) 平均O(h)
BFSO(n) 最坏, O(log n) 平均O(w)
无剪枝递归O(n)O(h)

算法过程

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

  1. root.val = 10∈ [7,15] → 累加10,递归左右子树
  2. 左子树(5)5 < 7→ 只遍历右子树(7)
    • 7 ∈ [7,15]→ 累加7,左右子树为空
  3. 右子树(15)15 ∈ [7,15]→ 累加15,递归左右子树
    • 左子树为空
    • 右子树(18):18 > 15→ 只遍历左子树(为空)
  4. 总和 = 10 + 7 + 15 = 32

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

  1. 10 ∈ [6,10]→ 累加10
  2. 左子树(5)5 < 6→ 只遍历右子树(7)
    • 7 ∈ [6,10]→ 累加7
    • 左子树(6):6 ∈ [6,10]→ 累加6
  3. 右子树(15)15 > 10→ 只遍历左子树(13)
    • 13 > 10→ 只遍历左子树(为空)
  4. 总和 = 10 + 7 + 6 = 23

测试用例

publicstaticvoidmain(String[]args){Solutionsolution=newSolution();// 创建树节点TreeNodecreateNode(intval){returnnewTreeNode(val);}// 测试用例1:标准示例TreeNoderoot1=newTreeNode(10);root1.left=newTreeNode(5);root1.right=newTreeNode(15);root1.left.left=newTreeNode(3);root1.left.right=newTreeNode(7);root1.right.right=newTreeNode(18);System.out.println("Test 1: "+solution.rangeSumBST(root1,7,15));// 32// 测试用例2:另一个标准示例TreeNoderoot2=newTreeNode(10);root2.left=newTreeNode(5);root2.right=newTreeNode(15);root2.left.left=newTreeNode(3);root2.left.right=newTreeNode(7);root2.right.left=newTreeNode(13);root2.right.right=newTreeNode(18);root2.left.left.left=newTreeNode(1);root2.left.right.left=newTreeNode(6);System.out.println("Test 2: "+solution.rangeSumBST(root2,6,10));// 23// 测试用例3:空树System.out.println("Test 3: "+solution.rangeSumBST(null,1,10));// 0// 测试用例4:单节点在范围内TreeNoderoot4=newTreeNode(5);System.out.println("Test 4: "+solution.rangeSumBST(root4,5,5));// 5// 测试用例5:单节点不在范围内System.out.println("Test 5: "+solution.rangeSumBST(root4,6,10));// 0// 测试用例6:所有节点都在范围内TreeNoderoot6=newTreeNode(5);root6.left=newTreeNode(3);root6.right=newTreeNode(7);System.out.println("Test 6: "+solution.rangeSumBST(root6,1,10));// 15// 测试用例7:所有节点都不在范围内System.out.println("Test 7: "+solution.rangeSumBST(root6,8,10));// 0// 测试用例8:边界值TreeNoderoot8=newTreeNode(10);root8.left=newTreeNode(5);root8.right=newTreeNode(15);System.out.println("Test 8: "+solution.rangeSumBST(root8,10,10));// 10System.out.println("Test 9: "+solution.rangeSumBST(root8,5,15));// 30// 测试用例9:大范围System.out.println("Test 10: "+solution.rangeSumBST(root8,1,100));// 30}

关键点

  1. 边界处理
    • 空树返回0
    • 单节点
    • 范围边界值

常见问题

  1. 为什么不用中序遍历?
    • 中序遍历虽然能得到有序序列,但无法利用范围信息进行剪枝
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/12 12:22:36

开源CRM系统源码全新发布,定制化销售管理系统

温馨提示&#xff1a;文末有资源获取方式在当今竞争激烈的商业环境中&#xff0c;企业销售团队面临着客户关系管理复杂、销售效率低下等挑战。为了帮助企业实现数字化转型&#xff0c;一款全新的CRM客户关系管理系统源码正式推出。该系统基于先进的技术架构&#xff0c;提供完全…

作者头像 李华
网站建设 2026/4/16 12:57:28

Science:最终成为大师的大多都是中等生,而不是班里的学霸

我们都熟悉王安石笔下《伤仲永》的故事&#xff0c;那个天赋异禀的孩童最终“泯然众人”。在我们的成长中&#xff0c;也总有那么一两个令人艳羡的“别人家的孩子”——他们早慧、学什么都快&#xff0c;仿佛早早握紧了成功的门票。如今&#xff0c;社交媒体更将这种对“早慧”…

作者头像 李华
网站建设 2026/4/16 13:43:45

【Java毕设全套源码+文档】基于springboot的助农捐赠慈善服务平台设计与实现(丰富项目+远程调试+讲解+定制)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/4/15 10:37:08

【Java毕设源码分享】基于springboot+vue的热门游戏评级论坛的设计与实现(程序+文档+代码讲解+一条龙定制)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/4/16 13:44:43

四大核心技术架构:AI开发的高效协同之道

在AI应用开发的技术演进中&#xff0c;优秀的架构设计往往是效率与稳定性的双重保障。事件驱动架构、插件化扩展、资源池化管理、链式调用这四大核心技术&#xff0c;并非孤立的技术亮点&#xff0c;而是相互支撑、协同发力的有机整体。 JBoltAI框架将这四大架构深度融合&#…

作者头像 李华