从大量数字中删除数字

时间:2015-08-20 07:43:40

标签: c arrays linked-list range

我遇到了以下问题,我正在努力寻找更优化的解决方案。

假设您有0到9之间的数字范围:

Values: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
Index:  0, 1, 2, 3, 4, 5, 6, 7, 8, 9

现在,让我们说“删除”1,4,5和7:

Values: 0, -, 2, 3, -, -, 6, -, 8, 9
Index:  0, 1, 2, 3, 4, 5, 6, 7, 8, 9

如果没有值,则所有后续值都会向左移动:

Values: 0, 2, 3, 6, 8, 9
Index:  0, 1, 2, 3, 4, 5

索引1的值现在变为2(为1),索引2的值现在为3(为2),索引3的值现为6(为3)等。

这是问题所在。我需要更大规模地管理这个,高达数万个值。这些值的随机数将从原始连续范围中删除,并可能在之后添加(但不会以相同的顺序删除)。起始状态将始终是介于0和MAX_VAL之间的完整数字序列。

我尝试过的事情:

1)维护一个值数组,从该数组中删除值,并将所有值都移动一个。这会失败,因为您在刚删除的值之后迭代所有值,结果太慢了。之后获取给定索引的值非常快。

2)维护一个值的链接列表,并通过将其拉出列表来删除该值。这似乎在添加/删除值和获取给定索引的值时都很慢,因为我需要首先遍历列表。

3)跟踪“已删除”值,而不是保持从0到MAX_VAL的值的巨型数组/列表/等。如果删除的值存储在有序数组中,那么计算在给定索引之前和之后已删除了多少值变得微不足道,而只返回偏移索引。这种方法很有效,除了维护已删除值的有序数组并且迭代通过它的速度很慢,特别是如果删除的值的数量接近MAX_VAL。

是否有某种算法或技术可以更快更有效地处理这类问题?

2 个答案:

答案 0 :(得分:1)

  

是否有某种算法或技术可以更快更有效地处理这类问题?

答案很大程度上取决于典型的用例:

  • 这组数字通常是稀疏还是密集?
  • 您多久进行一次插入与删除与查找?
  • 在哪些模式中插入或删除数字(随机,连续,从结尾或开始)?
  • 有什么内存限制?

以下是通用解决方案的一些想法:

  • 创建一个存储范围而不是数字的结构。
  • 以单个条目开头:0 - MAX_VAL。
  • 范围可以包含子范围。得到的范围图形成了一棵树。
  • 删除一个数字会将一个叶子范围拆分为两个,从而创建两个新叶子。

当集合密集时(因为范围很小),此算法可以很好地执行。当你保持树平衡时,当图表增长(查找的O(log n))时,它仍然会表现得有些快。

答案 1 :(得分:0)

现在,让我们说你"删除" 1,4,5和7:

Values: 0, -100, 2, 3, -100, -100, 6, -100, 8, 9// use a unique value that doesn't used in array
Index:  0, 1, 2, 3, 4, 5, 6, 7, 8, 9