【问题标题】:Search list for objects valid in a time range在时间范围内有效的对象的搜索列表
【发布时间】:2025-11-30 02:55:02
【问题描述】:

我有以下数据结构,它描述了一个对象及其有效的时间段。假设下面的数字是 unix 时间戳。

{
  "id": 1234,
  "valid_from": 2000
  "valid_to": 4000
},
{
 "id": 1235,
 "valid_from": 1000,
 "valid_to": 2200,
}
...

我希望能够快速将这些项目存储在 JavaScript 中,然后查询在特定时间有效的项目。

例如,如果我要查询在 2100 有效的对象,我会得到 [1234, 1235]。如果我要查询在 3999 有效的对象,我会得到 [1234],而在 4999 什么也没有。

结构中的项目大小约为 50-100k,我希望查找速度快,但插入和删除可能会更慢。

项目将具有重复的 valid_from 和 valid_to 值,因此它需要支持重复项。项目将重叠。

我需要不断地将数据插入到结构中(可能是批量插入以进行初始加载,然后随着数据的变化一次性更新)。我还将定期修改记录,因此很可能是删除和插入。

我不确定以高效方式解决此问题的最佳方法是什么?

算法不是我的强项,但如果我知道正确的方法,我可以自己研究算法。

我的想法:

我最初在考虑修改二叉搜索树以支持重复键和最接近查找,但这仅允许我查询 > valid_from 或

这将涉及我将数组或树一分为二以查找所有项目 > valid_from,然后手动检查每个项目的 valid_to。

我想我可以有两棵搜索树,一棵用于 valid_to 和 valid_from,然后我可以检查结果重叠中的哪个 id 并返回这些 id?

这对我来说还是有点老套?有没有人可以推荐的更好的方法,或者是这样做的。

【问题讨论】:

  • 数据更新率是多少?
  • 无论如何 k-d-tree 将是您的解决方案,因为它可以处理多个搜索键 github.com/ubilabs/kd-tree-javascript
  • 它必须在 20 分钟内处理大约 5k 次更新,这不是很多。其中一些是替换(删除/插入),但大多数是插入。偶尔会修剪旧记录。
  • 好的,所以 -k-d-tree 可以处理这种情况,而且,如果你一直插入一个有趣的想法来尝试使用自平衡树,并且在 serach 上自己也可以平衡它们
  • 谢谢,看起来很有希望去看看。

标签: javascript algorithm range binary-search-tree b-tree-index


【解决方案1】:

假设您有两个列表:启动/开始和到期/结束。两者都按时间排序。

给定特定时间,您可以通过二分搜索找到每个列表中第一项满足条件的位置。你也可以通过二分查找插入到每个列表中。

例如,如果有 1000 个项目并且开始位置是 342,那么项目 1-342 是可能的,如果结束位置是 901,那么终止列表中的项目 901-1000 是可能的。您现在需要将两个子列表相交。

从开始的 1-342 和结束的 901-1000 中获取项目 ID,并将它们放在单独的数组中(提前分配)。对数组进行排序。遍历数组。每当同一个 ID 连续出现两次时,它就是一个命中,一个有效匹配。

【讨论】: