给定数组A,找到满足条件的连续子数组的数量:
子阵列中没有对
(i,j)
,i < j
和A[i] mod A[j]= M
1<=A[i]<=100000
我的方法:在
O(n^2)
时间复杂度中采用天真的方式,这很糟糕。
我可以将其缩小为(nlogn)
吗?
答案 0 :(得分:0)
基本上,我们需要找到所有对i < j
和A[i] mod A[j] = M
如果a mod b = m
,则a mod d = m, where d is a divisor of b and d > m
散列数组中的数字。对于数组中的每个数字a
,检查a - m
或a - m
的任何除数是否为数组中的元素且其索引是否大于a
的索引 - 枚举(a, a - m)
中的任何现有对(a, divisor of (a - m) > m)
或O(n sqrt n)
。
显然,任何满足条件的连续子阵列都位于任何这样的对之间。如果我们在区间树中聚合对,当我们遍历数组时,我们可以在O(log n)
时间内测试我们是否在一对中。一旦我们检测到我们正在重叠一对(树中的间隔),我们将窗口重置为(i + 1, j)
(其中(i,j)
是间隔)并继续计数;我们根据公式segment * (segment + 1) / 2
将可实现的最大段添加到总数中,减去先前的重叠计数。
答案 1 :(得分:0)
这是O(N)时间复杂度,但需要O(N + M)空间复杂度:
考虑数组:
计数器数组可以根据以前的值逐步构造:
当在索引i之前查找A [i]的最后一次出现时,我们需要保留字典(A [i],last-index-of-A [i])以进行快速查找。 因为我们只保留A [i] mod M =&gt;的值。一个O(M)字典会做。
我们现在只是总结计数器数组值:
Number of contiguous subarrays = Sum(C)
在这种情况下,我们将有27个连续的子阵列,这些子阵列都符合这一条件。