我正在接受数据结构的测试培训,但我无法解决这个问题:
设计一个保持序列a_1,...,a_n的数据结构 并可以对其执行两个操作:
- 将a_i设为值x
- 计算x在两个索引之间的序列中出现的次数: 我和j;只是为了确保我说清楚(我不擅长英语)这意味着 返回给定的
醇>|{a_k: a_k = x and i <= k <= j}|
:x,i,j。约束:
- a_i来自区间[0,...,10 ^ 9],
- n较小 - 小于10 ^ 5
这两个操作最多应在O(log n)时间内运行。不幸的是,我看到它的唯一方法是O(log ^ 2 n)。我们在节点中保留带有maps<int,int>
的间隔树,它计算x在子树中出现的次数。同样重要的是不要保留0次出现的映射值(内存复杂性)。
我怎样才能更好地解决它?有人可以帮忙吗?
答案 0 :(得分:6)
这是一个包含两个数据字段的BST:
BSTNode<E>{
int index;
E value;
BSTNode left, right;
}
按索引对树进行排序,以便搜索为O(lg n):这有助于插入和设置(seta_i to value x
)。
至count how many times value x occurs in a sequence between two indexes: i, j
x
的节点。这类似于对单个孩子http://www.geekviewpoint.com/java/bst/sum_single_children求助或按顺序访问叶子(来自同一站点)。编辑:
找到i
和j
的公共父级后,而不是遍历子树,可以简单地查找值的频率:每个节点(此处为commonParent)可以有一个频率图:Map<E,Integer> childrenFreq = new HashMap<E,Integer>()
。一旦在O(lg n)