给定大小为N的数组A,如何计算对的数量(A[i]
,A[j]
),使它们之间的绝对差值小于或等于K,其中K为任意积极的自然数? (i
,j<=N
和i!=j
)
我的方法:
对数组进行排序。
创建另一个数组,存储两个连续数字之间的绝对差值。
我是朝着正确的方向前进吗?如果是,那我该如何进一步?
答案 0 :(得分:1)
您的方法部分正确。您首先对数组进行排序。然后保留两个指针i和j。
1. Initialize i = 0, j = 1.
2. Check if A[j] - A[i] <= K.
- If yes, then increment j,
- else
- **increase the count of pairs by C(j-i,2)**.
- increment i.
- if i == j, then increment j.
3. Do this till pointer j goes past the end of the array. Then just add C(j-1,2) to the count and stop.
通过i和j,你基本上维持一个窗口,在这个窗口中,元素之间的差异是&lt; = K。
编辑:这是基本的想法,你必须检查边界条件。此外,您还必须跟踪添加到计数中的过去间隔。您需要用当前间隔减去重叠,以避免重复计算。
复杂性:O(NlogN),对于排序操作,对于数组遍历是线性的
答案 1 :(得分:1)
这是O(n ^ 2):
Sort the array
For each item_i in array,
For each item_j in array such that j > i
If item_j - item_i <= k, print (item_j, item_i)
Else proceed with the next item_i
答案 2 :(得分:0)
对数组进行排序后,可以在O(N)时间内计算总和。
这里有一些代码。 O(N)算法是pair_sums,而pair_sums_slow是明显正确的,但是O(N ^ 2)算法。我在最后运行了一些测试用例,以确保两个算法返回相同的结果。
def pair_sums(A, k):
A.sort()
counts = 0
j = 0
for i in xrange(len(A)):
while j < len(A) and A[j] - A[i] <= k:
j+=1
counts += j - i - 1
return counts
def pair_sums_slow(A, k):
counts = 0
for i in xrange(len(A)):
for j in xrange(i+1, len(A)):
if A[j] - A[i] <= k:
counts+=1
return counts
cases = [
([0, 1, 2, 3, 4, 5], 10),
([0, 0, 0, 0, 0], 1),
([0, 1, 2, 4, 8, 16], 9),
([0, -1, -2, 1, 2], 2)
]
for A, k in cases:
want = pair_sums_slow(A, k)
got = pair_sums(A, k)
if want != got:
print A, k, want, got
pair_sums
背后的想法是,对于每个i,我们找到最小的j,使得A [j] - A [i]> K(或j = N)。然后j-i-1是以i为第一个值的对的数量。
因为数组已经排序,j只会随着i的增加而增加,所以整体复杂度是线性的,因为尽管有嵌套循环,但内部操作j+=1
最多可以出现N次。
答案 3 :(得分:0)
这是 O(nlogn)算法: -
1. sort input
2. traverse the sorted array in ascending order.
3. for A[i] find largest index A[j]<=A[i]+k using binary search.
4. count = count+j-i
5. do 3 to 4 all i's
时间复杂度: -
Sorting : O(n)
Binary Search : O(logn)
Overall : O(nlogn)