原贴地址:http://blog.leanote.com/post/dawnmagnet/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
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/range-sum-of-bst
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路分析
对于树的题目,一般就两种办法,遍历和递归。因为只有这样我们才能获取树的每一个元素。而这两种方法本质上没有什么质的区别,只有表达形式的区别。
对于这个题目来说,有一个非常简单的办法,就是统计每一个数字,如果这个数字num满足
n
u
m
<
=
h
i
g
h
并
且
n
u
m
>
=
l
o
w
num<=high并且 num>=low
num<=high并且num>=low,我们就统计这个数字。
class Solution {
public:
int rangeSumBST(TreeNode* root, int& low, int& high) {
if (root == nullptr) return 0;
int res = 0;
if (root->val >= low && root->val <= high) res += root->val;
res += rangeSumBST(root->left, low, high);
res += rangeSumBST(root->right, low, high);
return res;
}
};
这是我们写出的第一版代码,原理就是统计该二叉树中所有的满足条件的数字,并且对于每一个有分叉的节点,统计他们的左子树和右子树。
但是我们注意到题目中给我们的条件是二叉搜索树,可是我们甚至没有用上这个条件就做完了题目!
为了充分发挥题目给我们的条件,我们进行一个判断,对于一棵子树的根节点的来说,如果它小于low,那么我们就无需判断该节点的左子树,因为它的左子树都小于low,不会出现在答案里。如果它大于high,同理,就无需判断它的右子树,因为大于high的值也不会出现在答案里。
Rust代码
use std::rc::Rc;
use std::cell::RefCell;
impl Solution {
pub fn range_sum_bst(root: Option<Rc<RefCell<TreeNode>>>, low: i32, high: i32) -> i32 {
if let Some(node) = root {
let node = node.borrow();
let mut res = 0;
if node.val >= low {
res += Self::range_sum_bst(node.left.to_owned(), low, high);
}
if node.val <= high {
res += Self::range_sum_bst(node.right.to_owned(), low, high);
}
if node.val >= low && node.val <= high {
res += node.val;
}
res
} else {
0
}
}
}
C++代码
class Solution {
public:
int rangeSumBST(TreeNode* root, int& low, int& high) {
if (root == nullptr) return 0;
int res = 0;
if (root->val >= low && root->val <= high) res += root->val;
if (root->val >= low) res += rangeSumBST(root->left, low, high);
if (root->val <= high) res += rangeSumBST(root->right, low, high);
return res;
}
};