arrays - 在数组中搜索特定范围内的整数

标签 arrays algorithm search tree

有人可以给我解决以下问题的想法吗?

给定一个数组 ar[]长度n ,以及一些查询,每个查询的形式都是 a, b, c ,找到索引最小的数i这样索引位于 [c, n] 范围内这样 a < ar[i] < b .有(n - 1)总共c来自 1n - 1 .每个查询的预期复杂度应约为 O(log n) ,以及最多 复杂度的预计算 O(n log n) 是合适的。凭直觉,我想到了线段树,但我想不出构建它的方法,也想不出每个节点要保留什么。

最佳答案

好的,我认为我应该实现我与 user12861 讨论的 O(nlogn)/O(logn) 解决方案。

代码通过构建 n 树来工作,每个 c 一棵树。每棵树与较小的树共享其大部分内容,最多有 logn 个新节点。这样,预处理的总内存和时间成本限制为 O(nlogn)

实际的树与区间树非常相似。节点存储它们跨越的最小值和最大值,以及它们包含的最小索引。然而,我的实现不是自平衡的,但这可以使用您最喜欢的启发式方法添加。

import sys

class Node:
    pass
class Interval(Node):
    def __init__(self,left,val,i,right):
        self.i = i; self.val = val
        self.left = left; self.right = right
        self.mini = min(left.mini, i, right.mini)
        self.min = min(left.min, val, right.min)
        self.max = max(left.max, val, right.max)
    def add(self,val,i):
        # We do naive inserting here. In a real worst case logn solution,
        # self-balancing would take place here.
        if (val,i) < (self.val,self.i): return Interval(self.left.add(val,i), self.val, self.i, self.right)
        if (self.val,self.i) < (val,i): return Interval(self.left, self.val, self.i, self.right.add(val,i))
        return self
    def query(self,a,b):
        # If the entire interval is covered, return mini, this is what keeps us
        # at max 2 opened nodes per level in the tree.
        if a <= self.min and self.max <= b: return self.mini
        # Otherwise compose an answer from the subtrees.
        res = sys.maxint
        if a <= self.val <= b: res = min(res, self.i)
        if self.left.min <= b and self.left.max >= a: res = min(res, self.left.query(a,b))
        if self.right.min <= b and self.right.max >= a: res = min(res, self.right.query(a,b))
        return res
class Tip(Node):
    def __init__(self):
        # This is a typical null-pattern idiom. The self.values are set to
        # the min/max identities to ensure to interference with the upwards
        # value propagation.
        self.mini = sys.maxint
        self.min = sys.maxint
        self.max = -sys.maxint
    def add(self,val,i):
        return Interval(Tip(), val, i, Tip())
    def query(self,a,b):
        return sys.maxint

# The input data array
data = [0, 3, 1, 2, 0, 4, 9, 6, 1, 7]
N = len(data)

# Build the array of trees. O(nlogn)
ar = [None]*N + [Tip()]
for i in range(N-1, -1, -1):
    ar[i] = ar[i+1].add(data[i],i)

# The query function. O(logn)
def query(a,b,c):
    return ar[c].query(a,b)

# Test
print query(2, 7, 4) # = 5

关于arrays - 在数组中搜索特定范围内的整数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8504248/

相关文章:

php - 如何在 PHP 中使用 array_walk 对三维数组进行排序?

algorithm - 如何检查二部图中是否存在简单路径

mysql搜索,返回搜索成功的列名

java - 使用二维数组时出现运行时异常

c++ - 多维数组c++

ios - 如何计算 Swift 数组中元素的出现次数?

algorithm - 改进的背包算法

c++ - 在方阵中,每个单元格都是黑色或白色。设计一个算法来找到最大子正方形,使得所有 4 个边框都是黑色

search - 复杂的 SOLR 查询,包括 NOT 和 OR

testing - JIRA:如何让搜索框记住项目代码?