📅  最后修改于: 2023-12-03 14:49:36.021000             🧑  作者: Mango
有两个长度相等的整型数组,我们需要计算共有多少不同的索引对 (i, j) 满足:
我们可以使用双重循环暴力计算,但时间复杂度为 O(n^2),不够优秀。下面介绍两种更好的解决方案。
首先,我们对第一个数组 a 和第二个数组 b 进行排序。然后,我们使用两个指针 i 和 j 分别指向 a 和 b 的最左侧,对于每个 i,我们需要移动 j,直到找到最小的满足条件 a[i] + a[j] > b[i] + b[j] 的 j,这时,从 i 到 j-1 的所有 j 都可以满足条件。
C++ 代码:
int count(vector<int>& a, vector<int>& b) {
int n = a.size(), ans = 0;
sort(a.begin(), a.end());
sort(b.begin(), b.end());
for (int i = 0, j = 0; i < n; i++) {
while (j < n && a[i] + a[j] <= b[i] + b[j]) j++;
ans += n - j;
}
return ans;
}
时间复杂度为 O(nlogn),空间复杂度为 O(1)。由于只涉及指针移动,因此算法也非常快。
为了避免对数组进行排序,我们可以使用哈希表。具体而言,我们使用一个哈希表记录数组 a 中的每个元素出现次数,然后对于每个元素 a[i],我们枚举 b 中的每个元素,计算 a[i] + b[j] 的值,并查找有多少元素小于该值。特别地,当 a[i] + b[j] <= b[i] + b[j] 时,我们可以直接跳过该 j 的值。
C++ 代码:
int count(vector<int>& a, vector<int>& b) {
int n = a.size(), ans = 0;
unordered_map<int, int> cnt;
for (int x : a) cnt[x]++;
for (int i = 0; i < n; i++) {
for (int j = 0; j < i; j++) {
if (a[i] + a[j] > b[i] + b[j]) ans += cnt[a[i] + a[j]];
if (a[i] + b[j] > b[i] + b[j]) ans += cnt[a[i] + b[j]] - (a[i] == b[j] ? 1 : 0);
}
}
return ans;
}
时间复杂度为 O(n^2),空间复杂度为 O(n)。由于需要使用哈希表,因此算法较慢,而且需要额外的空间。
以上是两种解决方案,每种方案都有其优缺点。根据具体情况,选择最适合自己的方案。