📅  最后修改于: 2023-12-03 15:25:40.202000             🧑  作者: Mango
本题的问题是在一个数组中找出总和大于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)。
这个问题看起来比较简单,但其实有一些技巧。以下是两种解决方案:
最简单的方法是对数组中的所有子序列求和,然后判断他们是否大于0。这样做时间复杂度是 $O(n^3)$,显然难以通过大规模的测试数据。
另外一种更为高效的算法是使用双指针法。具体来说,我们首先对原始数组进行排序,然后使用双指针遍历数组。
指针 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)$,可以通过大规模的测试数据。