给定二叉搜索树的根结点
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提示:
- 树中节点数目在范围
[1, 2 * 104]
内1 <= Node.val <= 105
1 <= low <= high <= 105
- 所有
Node.val
互不相同
/**
中序+二分
思路出来的很快,有手就能写的代码也写得很快,但是效果很差。
**/
class Solution {
List<Integer> l=new ArrayList<Integer>();
public int rangeSumBST(TreeNode root, int low, int high) {
inorder(root);
int left=binarySearch(l,low);
int right=binarySearch(l,high);
if(left==-1||right==-1)return -1;
int sum=0;
for(int i=left;i<=right;i++){
sum+=l.get(i);
}
return sum;
}
public void inorder(TreeNode root){
if(root==null)return;
inorder(root.left);
l.add(root.val);
inorder(root.right);
}
public int binarySearch(List<Integer> l,int target){
int left=0,right=l.size()-1;
while(left<=right){
int mid=left+(right-left)/2;
if(l.get(mid)>target){
right=mid-1;
}else if(l.get(mid)<target){
left=mid+1;
}else{
return mid;
}
}
return -1;
}
}
/*
深度优先
①如果root为空,则返回0
②如果root.val<low,则忽略左子树在右子树找
③如果root.val>high,则忽略右子树在左子树找
④如果low<=root.val<=high,则将root加入并继续搜索左右子树
*/
class Solution {
public int rangeSumBST(TreeNode root, int low, int high) {
if(root==null)return 0;
if(root.val<low)return rangeSumBST(root.right,low,high);
if(root.val>high)return rangeSumBST(root.left,low,high);
return root.val+rangeSumBST(root.left,low,high)+rangeSumBST(root.right,low,high);
}
}
/*
广度优先:
定义一队列存储符合条件的根节点(剪枝
root表示遍历到的节点
①如果root=null,跳过不处理
②如果root.val<low,将右子树根节点加入队列
③如果root.val>high,将左子树根节点加入队列
④否则,将当前节点值加入结果并将左右子树加入队列
*/
class Solution {
public int rangeSumBST(TreeNode root, int low, int high) {
int ans=0;
Queue<TreeNode> q=new LinkedList<TreeNode>();
q.offer(root);
while(!q.isEmpty()){
root=q.poll();
if(root==null)continue;
if(root.val<low)q.offer(root.right);
else if(root.val>high)q.offer(root.left);
else{
ans+=root.val;
q.offer(root.left);
q.offer(root.right);
}
}
return ans;
}
}