📌  相关文章
📜  计数两个总和等于K的数组中的对(1)

📅  最后修改于: 2023-12-03 15:27:57.161000             🧑  作者: Mango

计数两个总和等于K的数组中的对

在编写程序时,我们常常需要计算数组中总和等于给定值K的元素对。这个问题在实际开发中非常常见,比如说在搜索引擎中,我们需要查找某个关键词是否同时出现在同一个页面内,就可以用这种方法。

解法1: 双层循环

最朴素也最容易想到的方法就是双层循环。我们可以枚举每一个数,然后再嵌套一层循环枚举其余所有数,如果加起来等于K,就说明找到一对元素。

def count_pairs(arr, K):
    count = 0
    for i in range(len(arr)):
        for j in range(i + 1, len(arr)):
            if arr[i] + arr[j] == K:
                count += 1
    return count

这个方法的时间复杂度为$O(n^2)$,对于大规模的数据集来说,性能会非常差,不适用于实际应用中。

解法2: 使用哈希表

上述方法的性能瓶颈在于双层循环,我们需要想办法优化这一过程。可以想到,当我们枚举到一个数时,如果我们能够在常数时间内判断K减去当前数是否在数组中出现过,那么时间复杂度就能够降低到$O(n)$。

我们可以使用哈希表来存储已经出现过的元素,这样我们只需要遍历一次数组,对于每一个数,我们先在哈希表中查找是否有与其匹配的元素,如果有,就说明找到了一对元素。

def count_pairs(arr, K):
    count = 0
    hash_map = {}
    for i in range(len(arr)):
        if K - arr[i] in hash_map:
            count += hash_map[K - arr[i]]
        hash_map[arr[i]] = hash_map.get(arr[i], 0) + 1
    return count

这个方法的时间复杂度为$O(n)$,比双层循环快了很多。但是需要考虑到哈希表可能造成额外的空间开销,对于非常稀疏的数据集来说,这个方法的空间开销会很大。

解法3: 排序+双指针

如果我们将数组排序,那么就可以使用双指针来查找数组中的元素对。我们使用两个指针$left$和$right$,分别指向数组的首尾两个元素,如果它们的和小于$K$,就将$left$向右移动一位,否则将$right$向左移动一位,直到找到满足条件的元素对。这个方法的时间复杂度为$O(nlogn)$,因为需要排序。

def count_pairs(arr, K):
    count = 0
    arr.sort()
    left, right = 0, len(arr) - 1
    while left < right:
        if arr[left] + arr[right] == K:
            count += 1
            left += 1
            right -= 1
        elif arr[left] + arr[right] < K:
            left += 1
        else:
            right -= 1
    return count

这个方法需要预处理一次,将数组排序,后面的查找过程可以在$O(n)$的时间内完成,因此适用于需要多次查找的情景。

总结

以上三种方法都是常见的求解数组元素对问题的方法。其中哈希表法可以在理论上实现$O(n)$的时间复杂度,但是空间开销会较大,因此需要权衡。排序+双指针法具有较好的实际效果,但需要预处理一次排序,适用于多次查找的场景。