【问题标题】:Zero sum minimal subarray [duplicate]零和最小子数组
【发布时间】:2012-02-27 10:54:52
【问题描述】:

可能重复:
Zero sum SubArray

一个数组同时包含正元素和负元素,找到 和等于 0 的子数组。

这是一道面试题。 不幸的是,我无法阅读这个question 的公认答案,所以我再次问它:如何找到零和的最小整数子数组?

注意,这不是“零子集问题”。显而易见的蛮力解决方案是 O(N^2) (遍历所有子阵列)。我们可以在 O(N) 中解决它吗?

【问题讨论】:

  • 如果您认为这是一个骗子,请不要发布该问题。如果您认为答案不足:您应该对它们发表评论和/或悬赏这个 [原始] 问题以引起更多关注。
  • @amit 原来的“零和子数组”问题被打破,正如迈克尔在这个问题中所说的那样!接受的答案有一个不再可用的链接

标签: arrays algorithm


【解决方案1】:

这个算法会找到所有的,你可以很容易地修改它来找到最小的子数组。

给定一个int[] input array,您可以创建一个int[] tmp 数组,其中tmp[i] = tmp[i - 1] + input[i]; 以便在 tmp 的每个元素处存储直到该元素的输入总和。

现在,如果您检查 tmp,您会注意到可能存在彼此相等的值。假设这些值位于索引jkj < k,那么总和为0 的子数组将从索引j + 1k。注意:如果j + 1 == k,然后k is 0,就是这样! ;)

注意:算法应考虑虚拟tmp[-1] = 0;

可以通过不同的方式实现实现,包括使用 BrokenGlass 建议的 HashMap,但请注意上述注释中的特殊情况。

例子:

int[] input = {4,  6,  3, -9, -5, 1, 3, 0, 2}
int[] tmp =   {4, 10, 13,  4, -1, 0, 3, 3, 5}
  • 注意 tmp 中索引 0 和 3 处的值 4 ==> 和 tmp 1 到 3 = 0,长度 (3 - 1) + 1 = 4
  • 注意 tmp 中索引 5 处的值 0 ==> sum tmp 0 到 5 = 0,长度 (5 - 0) + 1 = 6
  • 注意 tmp 中索引 6 和 7 处的值 3 ==> 和 tmp 7 到 7 = 0,长度 (7 - 7) + 1 = 1

【讨论】:

    【解决方案2】:

    一个数组包含正元素和负元素,找到 和等于 0 的子数组。

    是的,这可以在 O(n) 中完成。如果子数组中的元素之和为零,则意味着子数组之前的第一个元素的元素之和与子数组中最后一个元素的元素之和相同。

    遍历数组并为每个元素 K 将总和 K 和索引 K 放入哈希表中,如果当前元素的总和已经存在,则检查该元素和当前元素的索引,如果 delta小于最小子数组长度,更新最小值。用 (sum, current index K) 更新哈希表。

    【讨论】:

    • 不过,当您在哈希表中搜索每个元素时,这并不是真正的 O(n)。
    • O(1) 在哈希表/映射中查找具有相同总和的最后一个索引,总和是映射中的关键
    • 仅当可能的总和数量有限时。
    • @Detheroc:虽然你是正确的使用哈希表操作不是O(1) 最坏的情况,但它是平均情况。对于几乎任何情况,此解决方案都将提供O(n) 运行时间,但在某些奇异的边缘情况下,它确实可能会变成O(n^2) 最坏情况。如果您担心这些最坏的情况,您可以使用平衡树或其他排序容器,并获得O(nlogn)最差+平均时间复杂度。
    猜你喜欢
    • 2017-04-16
    • 2013-06-04
    • 2019-01-19
    • 1970-01-01
    • 1970-01-01
    • 2012-10-12
    • 1970-01-01
    • 2014-08-26
    • 2014-11-15
    相关资源
    最近更新 更多