题目
给定二叉搜索树的根结点 root,返回 L 和 R(含)之间的所有结点的值的和。
二叉搜索树保证具有唯一的值。
示例 1:
输入:root = [10,5,15,3,7,null,18], L = 7, R = 15
输出:32
示例 2:
输入:root = [10,5,15,3,7,13,18,1,null,6], L = 6, R = 10
输出:23
提示:
- 树中的结点数量最多为 10000 个。
- 最终的答案保证小于 2^31。
思路一 ——递归
由于二叉搜索树的特点(左子树比根结点小,右子树比根结点大),可以采用递归实现深度优先遍历。
- 递归基本项:node.val<= R && node.val >= L 成立,则ret += node.val;
- 递归项:如果node.val < L,则递归右子树;如果node.val > R,则递归左子树;
- 递归终止条件:node == null为真
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
//Step1: 定义结果变量
int ret;
public int rangeSumBST(TreeNode root, int L, int R) {
ret = 0;
//Step2:深度优先遍历
dfs(root, L, R);
//Step3:返回结果
return ret;
}
private void dfs(TreeNode root, int L, int R){
if(root != null){
if(L <= root.val && root.val <= R){
ret += root.val;
dfs(root.left, L, R);
dfs(root.right, L, R);
}else if( L > root.val){
dfs(root.right, L, R);
}else{
dfs(root.left, L, R);
}
}
}
}
也可以递归调用本函数:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public int rangeSumBST(TreeNode root, int L, int R) {
//Step1:判断特殊情况
if(root == null) return 0;//也是递归调用的终止条件
int ret = 0;//定义结果变量
//Step2:递归调用本函数
if(L <= root.val && root.val <= R){
ret += root.val;
ret += rangeSumBST(root.left, L, R);
ret += rangeSumBST(root.right, L, R);
}else if( L > root.val){
ret += rangeSumBST(root.right, L, R);
}else{
ret += rangeSumBST(root.left, L, R);
}
//Step3:返回结果
return ret;
}
}
思路二——栈
可以使用栈保存当前结点,如果该结点值在(L,R)范围内,结果累加该值,否则,判断该结点左右子树是否为空,不为空返回加入该栈中。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public int rangeSumBST(TreeNode root, int L, int R) {
//Step1:定义结果变量
int ret = 0;
//Step2:判断特殊情况
if(root == null) return ret;
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
//Step3:广度优先遍历
while(!stack.isEmpty()){
TreeNode temp = stack.pop();
if(temp.val <= R && temp.val >= L){
ret += temp.val;
}
if(temp.left != null) stack.push(temp.left);
if(temp.right != null) stack.push(temp.right);
}
//Step4:返回结果
return ret;
}
}
上述代码没有利用二叉搜索树的特性,下面是利用该特性的代码(降低了时间复杂度):
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public int rangeSumBST(TreeNode root, int L, int R) {
//Step1:定义结果变量
int ret = 0;
//Step2:判断特殊情况
if(root == null) return ret;
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
//Step3:广度优先遍历
while(!stack.isEmpty()){
TreeNode temp = stack.pop();
if(temp.val <= R && temp.val >= L){
ret += temp.val;
if(temp.right != null) stack.push(temp.right);
if(temp.left != null) stack.push(temp.left);
}else if(temp.val < L){
if(temp.right != null) stack.push(temp.right);
}else{
if(temp.left != null) stack.push(temp.left);
}
}
//Step4:返回结果
return ret;
}
}