赞
踩
对于一个数组,我们可以对其建立一棵 线段树, 每个结点存储一个额外的值 count 来代表这个结点所指代的数组区间内的元素个数. (数组中并不一定每个位置上都有元素)
实现一个 query 的方法,该方法接受三个参数 root, start 和 end, 分别代表线段树的根节点和需要查询的区间,找到数组中在区间[start, end]内的元素个数。[0, 3, count=3]
/ \
[0,1,count=1] [2,3,count=2]
/ \ / \
[0,0,count=1] [1,1,count=0] [2,2,count=1], [3,3,count=1]query(1, 1), return 0
query(1, 2), return 1
query(2, 3), return 2
性质:父亲的区间是[a,b],(c=(a+b)/2)左儿子的区间是[a,c],右儿子的区间是[c+1,b],线段树需要的空间为数组大小的四倍
/**
* Definition of SegmentTreeNode:
* public class SegmentTreeNode {
* public int start, end, count;
* public SegmentTreeNode left, right;
* public SegmentTreeNode(int start, int end, int count) {
* this.start = start;
* this.end = end;
* this.count = count;
* this.left = this.right = null;
* }
* }
*/
public class Solution {
/**
*@param root, start, end: The root of segment tree and
* an segment / interval
*@return: The count number in the interval [start, end]
*/
public int query(SegmentTreeNode root, int start, int end) {
// write your code here
//参数检查
if(root == null ||start > end)
return 0;
//节点区间位于查询区间内
if(start <= root.start && end >= root.end)
return root.count;
int mid = root.start + (root.end - root.start)/2;
//拆分
if(start > mid)//右子树
return query(root.right,start,end);
else if(end < mid+1)//左子树
return query(root.left,start,end);
else//位于邻接区
return query(root.left,start,mid) + query(root.right,mid+1,end);
}
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。