题目
给定二叉搜索树的根结点 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
分析
这道题要求的就是一棵树中所有>=L并且<=R的节点的值的求和.也就是遍历这棵树然后判断值大小并求和
代码
第一种解法:
使用非递归方式对而参数进行前序遍历并求和
public int rangeSumBST(TreeNode root, int L, int R) {
Stack<TreeNode> stack = new Stack<>();
int sum = 0;
stack.push(root);
while (!stack.isEmpty()) {
TreeNode cur = stack.pop();
if (cur.val >= L && cur.val <= R) {
sum = sum + cur.val;
}
if (cur.right != null) {
stack.push(cur.right);
}
if (cur.left != null) {
stack.push(cur.left);
}
}
return sum;
}
第二种解法:
使用递归方式遍历并求和
int sum = 0 ;
/**
* 前序遍历
* 递归做法,注意的是递归确实快了一点,但是不知道为啥会快
* @param root
* @param L
* @param R
* @return
*/
public int rangeSumBST2(TreeNode root, int L, int R) {
DFS(root,L,R);
return sum;
}
private void DFS(TreeNode node,int L,int R){
if(node.val>=L && node.val <= R){
sum = sum + node.val;
}
if(node.right != null){
DFS(node.right,L,R);
}
if(node.left != null){
DFS(node.left,L,R);
}
}
这种方式比非递归遍历要快一点,应该是jvm对递归做了优化
第三种解法:
由于这是个二叉搜索树,也就是说,我们进行中序遍历时它是排好序的.那么我们就可以在遇到小于L的节点时不再遍历其左子树,在遇到大于R的节点时不再遍历其右子树,省掉不需要的遍历.
int sum = 0;
/**
* 中序遍历,因为是有顺序的,所以在小于L和大于R的都不用再遍历,
* 速度最快.
* @param root
* @param L
* @param R
* @return
*/
public int rangeSumBST3(TreeNode root, int L, int R) {
inOrder(root,L,R);
return sum;
}
private void inOrder(TreeNode node,int L,int R){
if(node == null){
return;
}
if( node.val <L){
inOrder(node.right,L,R);
}
if(node.val>R){
inOrder(node.left,L,R);
}
if(node.val >= L && node.val <=R){
inOrder(node.left,L,R);
sum = sum+node.val;
inOrder(node.right,L,R);
}
}