📜  门| GATE-CS-2006 |第54章

📅  最后修改于: 2021-07-02 16:29:50             🧑  作者: Mango

给定两个数字数组a 1 ,a 2 ,a 3 ,…a n和b 1 ,b 2 ,.. b n ,其中每个数字为0或1,这是找到最大跨度(i,j)的最快算法,例如那a i + a i + 1 ,….a j = b i + b i + 1 ,.. b j 。或报告没有这样的跨度,
(A)如果允许散列,则花费O(n 3 )和Ω(2 n)时间
(B)在关键比较模型中花费O(n 3 )和Ω(n 2.5)时间
(C)取θ(n)的时间和空间
(D)仅当2n个元素的和为偶数时才花费O(√n)时间答案: (C)
说明:该问题可以用θ(n)的时间和空间来解决。

这个想法是基于以下观察。

  1. 由于总共有n个元素,因此两个数组的最大和为n。
  2. 两个和之间的差从-nn 。因此,总共有2n +1个可能的差值。
  3. 如果两个数组的前缀和之间的差在两个点处相同,则这两个点之间的子数组具有相同的和。

以下是完整算法。

  1. 创建大小为2n + 1的辅助数组,以存储所有可能的差值的起点(请注意,差的可能值从-n到n不等,即,总共有2n + 1个可能值)
  2. 将所有差异的起始点初始化为-1。
  3. maxLen初始化为0,并将两个数组的前缀和都初始化为0,preSum1 = 0, preSum2 = 0
  4. 从i = 0到n-1遍历两个数组。
    1. 更新前缀总和:preSum1 + = arr1 [i],preSum2 + = arr2 [i]
    2. 计算当前前缀总和的差: curr_diff = preSum1 – preSum2
    3. 在差异数组中查找索引: diffIndex = n + curr_diff // curr_diff可以为负,并且可以一直到-n
    4. 如果curr_diff为0,则到目前为止i + 1为maxLen
    5. 否则,如果第一次看到curr_diff,即当前diff的起始点为-1,则将起始点更新为i
    6. 否则(第一次未看到curr_diff),然后将i视为终点并找到当前相同总和跨度的长度。如果此长度更大,则更新maxLen
  5. 返回maxLen

有关完整的运行代码,请参见两个二进制数组中具有相同总和的最长跨度
这个问题的测验