【发布时间】:2015-09-18 07:17:20
【问题描述】:
在一个未排序的数组中找到所有对,其总和可以被 4 整除。 请推荐一个比 O(n*n) 更好的算法
e.g.
[1,2,4,0,20,22]
k=4
[0,4]
[0,20]
[20,4]
[2,22]
【问题讨论】:
-
@user3676125 我可以使用额外的空间吗?
标签: arrays algorithm time-complexity big-o
在一个未排序的数组中找到所有对,其总和可以被 4 整除。 请推荐一个比 O(n*n) 更好的算法
e.g.
[1,2,4,0,20,22]
k=4
[0,4]
[0,20]
[20,4]
[2,22]
【问题讨论】:
标签: arrays algorithm time-complexity big-o
可以在O(n+k) 中完成,其中k 是此类对的数量(可以在O(n^2) 本身中)。
这个想法是创建 4 个列表 list0,list1,list2,list3,其中 list_i 包含所有元素 x 使得 x%4 ==i。
创建这些列表很简单,在O(n) 中完成。
一旦你有了这些列表,你所要做的就是获取所有对,其中一个元素来自list_i,另一个元素来自list_((4-i)%4)(所以list0+list0、list1+list3、list2+list2)。这可以非常简单地完成,并且会非常有效地生成所有对。
优化说明:它可以通过根据模数对数组本身“排序”来就地完成(非常少的额外空间),因此您将在数组本身中表示列表。
示例:(来自您的列表,修改最少)
array = [1,2,4,0,20,22,7]
生成列表:
list0 = [0,4,20]
list1 = [1]
list2 = [2,22]
list3 = [7]
现在,
"combine" list0 with itself: (0,4), (4,20), (0,20)
"combine" list2 with itself: (2,22)
"combine" list1 with list3: (1,7)
【讨论】:
arr=[3,711,...,4k+3] - k 在这种情况下实际上是 0。对于均匀分布的数字 - 是的,k 确实在 O(n^2) 中。