📜  总和大于0的数组中的对数(1)

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

总和大于0的数组中的对数

本题的问题是在一个数组中找出总和大于0的所有对数。例如,数组 [1,-1,2,3,-2] 中,总和大于0的对数有 (1,2), (1,3), (2,3), (1,-1,2), (1,-1,3), (1,2,3), (2,3,-2)。

这个问题看起来比较简单,但其实有一些技巧。以下是两种解决方案:

1. 完全枚举

最简单的方法是对数组中的所有子序列求和,然后判断他们是否大于0。这样做时间复杂度是 $O(n^3)$,显然难以通过大规模的测试数据。

2. 双指针

另外一种更为高效的算法是使用双指针法。具体来说,我们首先对原始数组进行排序,然后使用双指针遍历数组。

指针 i 和 j 分别指向数组中的首位和末尾。我们假设数组已经按照非降序排列。如果 nums[i] + nums[j] 大于0,那么所有介于 i 和 j 之间的元素都能和 j 相加形成一个正数,这时我们可以将 j 往左移动一位,尝试寻找更多的对数。如果 nums[i] + nums[j] 小于等于0,那么所有介于 i 和 j 之间的元素都不能和 j 形成一个正数,这时我们可以将 i 往右移动一位,去尝试找到更多的正数。

代码实现:

int countPositiveSumPairs(vector<int>& nums) {
    int count = 0;
    int i = 0, j = nums.size() - 1;
    sort(nums.begin(), nums.end()); // 排序
    while (i < j) {
        if (nums[i] + nums[j] > 0) {
            count += (j - i);
            j--;
        } else {
            i++;
        }
    }
    return count;
}

以上就是本题的两种解决方案。双指针算法的时间复杂度为 $O(n \log n)$,可以通过大规模的测试数据。