《数组元素的目标和》(双指针+二分答案)

55 阅读1分钟

双指针

#include <bits/stdc++.h>
using namespace std;
const int N = 100010;
int a[N], b[N];
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n, m, x;
    cin >> n >> m >> x;
    for (int i = 0; i < n; i ++) {
        cin >> a[i];
    }
    for (int i = 0; i < m; i ++) {
        cin >> b[i];
    }
    // sort(a, a + n);
    // sort(b, b + m);
    int p = 0, q = m - 1;//定义两个指针分别遍历两个数组
    while (p != n) {
        while (a[p] + b[q] > x && q >= 0) {
            // cout << a[p] << ' ' << b[q] << endl;
            q --;
        }//升序是此题双指针的基础,关键在于指针q不会回溯
        if (a[p] + b[q] == x) {
            break;
        }
        p ++;
    }//从而将时间复杂度由O(n^2) -> O(n);
    cout << p << ' ' << q << endl;
    return 0;
}

二分答案

#include <bits/stdc++.h>
using namespace std;
const int N = 100010;
int a[N], b[N];
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n, m, x;
    cin >> n >> m >> x;
    for (int i = 0; i < n; i ++) {
        cin >> a[i];
    }
    for (int j = 0; j < m; j ++) {
        cin >> b[j];
    }
    for (int i = 0; i < n; i ++) {//遍历数组a
        int l = 0, r = m - 1;
        while (l < r) {
            int mid = l + r >> 1;
            if (a[i] + b[mid] >= x) {
                r = mid;
            }
            else {
                l = mid + 1;
            }
        }//二分查找答案,原理为数组b是单调升序的
        if (a[i] + b[r] == x) {
            cout << i << ' ' << r << endl;
            return 0;
        }
    }
}