我最近在谷歌接受了采访.由于这个问题,我的过程在2轮之后没有向前推进.
Suppose you are given an array of numbers. You can be given queries
to:
- Find the sum of the values between indexes i and j.
- Update value at index i to a new given value.
- Find the maximum of the values between indexes i and j.
- Check whether the subarray between indexes i and j, both inclusive, is in ascending or descending order.
我给了他一个解决方案,但它是检查索引i和j之间的子阵列.他让我对它进行优化.我想使用哈希表,以便如果起始索引相同且结束索引大于上一个索引,我们存储最大值以及它是以升序还是降序并仅检查剩余的子阵列.但是,这并没有根据需要对其进行优化.
我很想知道如何优化解决方案以使其可以接受.
约束:
一切从[1,10 ^ 5]
谢谢 :)
最佳答案 在最坏的情况下,所有这些查询都可以在每个查询的O(log N)时间内回答(预处理的时间为O(N)).您可以构建一个段树,并为每个节点维护总和,最大值和两个布尔标志(它们指示对应于此节点的范围是否按升序/降序排序).所有这些值都可以有效地重新计算以用于更新查询,因为只有O(log N)个节点可以更改(它们位于从根到与更改元素对应的叶子的路径上).所有其他范围查询(sum,max,sorted or not)被分解为O(log N)节点(由于段树的属性),并且很容易将O(1)中两个节点的值组合在一起(例如,对于sum,组合2个节点的结果只是这些节点的值的总和.
这是一些伪代码.它显示了应该在节点中存储哪些数据以及如何组合2个节点的值:
class Node {
bool is_ascending
bool is_descending
int sum
int max
int leftPos
int rightPos
}
Node merge(Node left, Node right) {
res = Node()
res.leftPos = left.leftPos
res.rightPos = right.rightPos
res.sum = left.sum + right.sum
res.max = max(left.max, right.max)
res.is_ascending = left.is_ascending and right.is_ascending
and array[left.rightPos] < array[right.leftPos]
res.is_descending = left.is_descending and right.is_descending
and array[left.rightPos] > array[right.leftPos]
return res
}