📌  相关文章
📜  C ++程序查找所有零和的三元组(1)

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

C++程序查找所有零和的三元组

在这个问题中,我们需要在给定的整数数组中查找所有的三元组,使它们的和为零。这是一个普遍的问题,并且在许多算法面试中都会被问到。

为了解决这个问题,我们可以使用暴力方法和优化方法。在这篇文章中,我们将研究两种方法。

暴力方法

暴力方法非常直观,它考虑将所有可能的三元组组合成一起,并检查它们的和是否为零。

void findTriplets(vector<int>& arr) {
    int n = arr.size();
    bool found = false;
    // 包含所有可能的三元组
    for(int i=0; i<n-2; i++) {
        for(int j=i+1; j<n-1; j++) {
            for(int k=j+1; k<n; k++) {
                if(arr[i] + arr[j] + arr[k] == 0) {
                    cout << arr[i] << " "
                         << arr[j] << " "
                         << arr[k] << endl;
                    found = true;
                }
            }
        }
    }
    if(found == false) {
        cout << "不存在零和三元组" << endl;
    }
}

当数组大小为 n 时,上述代码的时间复杂度为 O(n^3)。

优化方法

暴力方法虽然可行,但时间复杂度很高,并且不适用于大型输入。因此,我们需要一些更优化的方法。

排序

我们可以首先对给定的数组进行排序。这将使我们更容易查找三元组,而不会错过任何方式。

sort(arr.begin(), arr.end());

排序的时间复杂度为 O(n log n)。

双指针方法

接下来,我们采用双指针方法来找到所有可能的三元组。首先,我们将第一个指针指向排序后的数组中的第一个元素,第二个指针指向第一个指针之后的元素,第三个指针指向数组的最后一个元素。

for(int i=0; i<n-2; i++) {
    int l = i+1, r = n-1;
    // 双指针方法
    while(l < r) {
        if(arr[i] + arr[l] + arr[r] == 0) {
            cout << arr[i] << " "
                 << arr[l] << " "
                 << arr[r] << endl;
            l++, r--;
            found = true;
        }
        else if(arr[i] + arr[l] + arr[r] < 0) {
            l++;
        }
        else {
            r--;
        }
    }
}

在每个循环迭代中,我们检查三个指针所指的元素之和是否为零。如果是,那么我们就找到了一组三元组,然后将两个指针向中心移动。如果和小于零,那么我们将左指针向右移动以增加和。如果和大于零,我们将右指针向左移动以减小和。

使用双指针方法,时间复杂度从 O(n^3) 降到了 O(n^2)。

完整代码
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

void findTriplets(vector<int>& arr) {
    int n = arr.size();
    bool found = false;
    sort(arr.begin(), arr.end());
    for(int i=0; i<n-2; i++) {
        int l = i+1, r = n-1;
        while(l < r) {
            if(arr[i] + arr[l] + arr[r] == 0) {
                cout << arr[i] << " "
                     << arr[l] << " "
                     << arr[r] << endl;
                l++, r--;
                found = true;
            }
            else if(arr[i] + arr[l] + arr[r] < 0) {
                l++;
            }
            else {
                r--;
            }
        }
    }
    if(found == false) {
        cout << "不存在零和三元组" << endl;
    }
}

int main() {
    vector<int> arr = {0, -1, 2, -3, 1};
    findTriplets(arr);
    return 0;
}
总结

在本文中,我们介绍了如何在给定数组中查找所有零和的三元组。我们看到了两种方法:暴力方法和优化方法。暴力方法虽然可行,但时间复杂度很高,并且不适用于大型输入。因此,我们采用了排序和双指针方法来找到所有可能的三元组。这种方法的时间复杂度为 O(n^2),并且适用于大型输入。