如何提高此算法的时间复杂度?

时间:2014-10-16 13:21:06

标签: algorithm time-complexity

  • n列表大小
  • v[n]列出所有值设置为0
  • 设置update(k, a)
  • v[k] += a操作
  • query(a, b)操作,返回v[a] + v[a+1] + ... + v[a+b]a<b
  • 的总和

这些操作使算法的时间复杂度为O(n * cost of one operation)

---------------------------
| update | query | total  |
---------------------------
|  O(1)  |  O(n) |  O(n)  |
---------------------------

是否有任何版本的updatequery操作可以提高总时间复杂度?

例如,我尝试在0操作中缓存nupdate之间的每个总和,但我得到了更慢的算法:

---------------------------
| update | query | total  |
---------------------------
| O(n^2) |  O(1) | O(n^2) |
---------------------------

有什么建议吗?

最糟糕的情况是我感兴趣的。

我已经知道两个版本:每个版本都有一个操作O(1)而另一个O(n)或更高版本。

2 个答案:

答案 0 :(得分:2)

正如Niklas所说,这个问题或多或少是为Fenwick trees设计的(你的查询可以作为两个前缀和的差异来回答)。我正在写这个答案,指出可以用不同的方式来换取运营成本。

首先,使用廉价查询的算法可以将其更新时间改进为O(n):提前计算前缀总和并使用上述差异技巧。此外,我们可以提取主要想法并将其应用于任何支持操作的数据结构

update(k, a, b): for i in a..b, do s[i] += k
query(i): return s[i],

其中s现在包含前缀sum而不是实际值。

现在,经典的Fenwick / segment树每个内部节点有d = 2个子节点(是二进制的)。没有什么能阻止我们选择其他d值。 updatequery必须访问节点及其祖先,而另一个必须访问包含输入间隔的段。前一种访问模式需要时间O(log n / log d)。后一种模式需要时间O(d(log n / log d))。在此框架中,您提出的算法实质上取d = n。通过获取d的其他值,我们可以考虑查询/更新操作的精确组合以及可能有利于更平坦的树结构的架构细节。

答案 1 :(得分:1)

感谢@Niklas B的评论之一。我继续关注细分树的研究。

细分树的表示

  • leaf节点是输入数组的元素
  • 每个内部节点表示叶节点的一些合并
  • 合并是节点下的叶子总和
  • 树的数组表示用于表示段树
  • 对于索引为i的每个节点,左边的子节点位于2*i+1,右边的子节点位于2*i+2,父节点位于floor((i-1)/2)

从给定数组构建段树

  • 以细分arr[0, .., n-1]
  • 开头
  • 将当前段分成两半(如果尚未成为长度为1的段)
  • 在两半上调用相同的过程,对于每个这样的段,我们将总和存储在相应的节点
  • 构建的分段树的所有级别将完全填充,但最后一级除外。
  • 树将是一个完整的二叉树,因为我们总是将每个级别的两个部分划分为
  • 由于构造的树总是带有n叶子的完整二​​叉树,因此会有n-1个内部节点
  • 节点总数将为2*n – 1

时间复杂度

  • 树构建O(n)
  • 总共2n-1个节点,每个节点的值仅在树构造中计算一次
  • 查询O(Logn)
  • 要查询总和,我们每个级别最多处理四个节点,级别数为O(Logn)。
  • 更新还有O(Logn)
  • 要更新叶值,我们处理每个级别的一个节点,级别数为O(Logn)

    -------------------------------
    | update  |  query  |  total  |
    -------------------------------
    | O(Logn) | O(Logn) | O(Logn) |
    -------------------------------
    

参考文献:

http://www.geeksforgeeks.org/segment-tree-set-1-sum-of-given-range/

http://en.wikipedia.org/wiki/Segment_tree