📌  相关文章
📜  使得第一数组的元素和更大的不同索引对(i,j)的计数(1)

📅  最后修改于: 2023-12-03 14:49:36.021000             🧑  作者: Mango

计算第一个数组中元素和更大的不同索引对的计数

有两个长度相等的整型数组,我们需要计算共有多少不同的索引对 (i, j) 满足:

  • 第一个数组中的元素和 (a[i] + a[j]) 大于第二个数组中对应元素的和 (b[i] + b[j]);
  • i < j;
  • 0 ≤ i,j < 数组长度。

我们可以使用双重循环暴力计算,但时间复杂度为 O(n^2),不够优秀。下面介绍两种更好的解决方案。

解决方案 1:排序 + 双指针

首先,我们对第一个数组 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)。由于只涉及指针移动,因此算法也非常快。

解决方案 2:哈希表

为了避免对数组进行排序,我们可以使用哈希表。具体而言,我们使用一个哈希表记录数组 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)。由于需要使用哈希表,因此算法较慢,而且需要额外的空间。

以上是两种解决方案,每种方案都有其优缺点。根据具体情况,选择最适合自己的方案。