Algorithm 回答IsOn(i)和Toggle(i,j)的理想数据结构应该比HashSet更好

Algorithm 回答IsOn(i)和Toggle(i,j)的理想数据结构应该比HashSet更好,algorithm,data-structures,Algorithm,Data Structures,这是我最近在一次采访中被问到的一个问题。我想出了一个不错的解决办法,但面试官告诉我还有一个更好的办法 想象一下,有n个灯泡(或者你选择的任何二进制东西),一开始它们都是关闭的。设计一种在理想时空复杂度下回答两个问题的方法: (1) IsOn(i)-如果元素“i”处于启用状态,则返回true (2) 切换(i,j)-更改范围[i,j](包括)中所有元素的状态 初始解决方案:一个数组。O(1)中的IsOn,O(j-i)中的Toggle,但是O(N)空间复杂度 更好的解决方案:保存所有打开的元素的哈希

这是我最近在一次采访中被问到的一个问题。我想出了一个不错的解决办法,但面试官告诉我还有一个更好的办法

想象一下,有n个灯泡(或者你选择的任何二进制东西),一开始它们都是关闭的。设计一种在理想时空复杂度下回答两个问题的方法:

(1) IsOn(i)-如果元素“i”处于启用状态,则返回true

(2) 切换(i,j)-更改范围[i,j](包括)中所有元素的状态

  • 初始解决方案:一个数组。O(1)中的IsOn,O(j-i)中的Toggle,但是O(N)空间复杂度
  • 更好的解决方案:保存所有打开的元素的哈希集。IsOn仍然是O(1),Toggle仍然是O(j-i),但空间复杂度要高得多

  • 有人告诉我应该找到一个更好的解决方案,一个与存储打开的元素的范围有关的解决方案,但我很难理解它。

    这可以通过延迟传播的段树来完成。算法如下

  • 最初,数组将填充0
  • 更新(i,j)将切换i到j范围内的值。这可以使用延迟传播在O(nlogn)中完成
  • 查询(l)将告诉我们索引[l,l]处的值

  • 时间复杂度O(nlogn)用于构建树,O(logn)用于查询和更新

    这两个操作都可以在O(logn)中完成。我现在不记得数据结构的名称。很可能是因为谢谢你的回答。我很难找到关于这个话题的好解释。你能告诉我一个吗?当然你应该看看为什么它比使用散列映射更好?这里你说你在O(nlogn)中得到了更新(i,j),但在散列映射中,它的O(j-i)并不比O(n)差。@marvel308困扰我的是空间复杂度——如果我正确理解“段树”,它的空间复杂度是原始数组的两倍(所以2N),支持“惰性”方法需要另一个大小为N的数组。考虑到我们的第一个解决方案,简单数组,由于具有O(N)空间复杂性而被取消资格,这是一个很大的空间!但是,我确实了解间隔树在不提高空间复杂度的情况下如何允许两个操作都使用log(n),这正是我想要的。