2020-41

226 阅读2分钟
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
/*
【2020统考真题】41
定义三元组(a,b,c)(a、b、c均为正数)的距离D=|a-b|+|b-c|+|c-a|
给定3个非空整数集合S1、S2和S3,按升序分别存储在3个数组中。
请设计一个尽可能高效的算法,计算并输出所有可能的三元组(a,b,c)(a∈S1,b∈S2,C∈S3)中的最小距离。
例如S1 ={-1,0,9},S2={-25,-10,10,11),S3={2,9,17,30,41},则最小距离为2,
相应的三元组为(9,10,9)。
要求:
1)给出算法的基本设计思想。
2)根据设计思想,采用C或C++语言描述算法,关键之处给出注释。
3)说明你所设计的算法的时间复杂度和空间复杂度。
*/

// 暴力 时间复杂度O(n^3) 空间复杂度O(1)
int minLength(const vector<int> &S1, const vector<int> &S2, const vector<int> &S3)
{
    int minDistance = INT_MAX; // 初始化最小距离为最大值,确保任何计算的距离都能更新它。

    // 三重循环遍历所有可能的三元组
    for (int a : S1)
    {
        for (int b : S2)
        {
            for (int c : S3)
            {
                int distance = abs(a - b) + abs(b - c) + abs(c - a); // 计算距离
                minDistance = min(minDistance, distance);            // 更新最小距离
            }
        }
    }

    return minDistance; // 返回最小距离
}

/*
abs(a - b) + abs(b - c) + abs(c - a)
假设 a < b < c,则三元组的最小距离就是 (b-a) + (c-b) + (c-a) = 2(c-a)= d
实际上距离的大小和中间点b没有关系,所以只要将a向右移动或者将c向左移动即可缩小距离d
*/

// 时间复杂度O(n1 + n2 + n3)或O(max(n1, n2, n3)) 空间复杂度 O(1)

int findMinDistanse(const vector<int> &S1, const vector<int> &S2, const vector<int> &S3)
{
    int minDistance = INT_MAX;
    int i = 0, j = 0, k = 0;
    while (i < S1.size() && j < S2.size() && k < S3.size())
    {
        int a = S1[i], b = S2[j], c = S3[k];
        int currentDistance = abs(a - b) + abs(b - c) + abs(a - c);

        minDistance = min(minDistance, currentDistance);

        if (a <= b && a <= c)
        {
            i++; // a 是当前最小的元素,所以我们增加指向 S1 的指针 i
        }
        else if (b <= a && b <= c)
        {
            j++; // b 是当前最小的元素,所以我们增加指向 S2 的指针 j
        }
        else
        {
            k++; // c 是当前最小的元素,所以我们增加指向 S3 的指针 k
        }
    }
    return minDistance;
}

int main()
{
    vector<int> S1 = {-1, 0, 9};
    vector<int> S2 = {-25, -10, 10, 11};
    vector<int> S3 = {2, 9, 17, 30, 41};

    int result1 = minLength(S1, S2, S3);
    int result2 = findMinDistanse(S1, S2, S3);
    cout << "最小距离 = " << result1 << endl; 
    cout << "最小距离 = " << result2 << endl; 
    return 0;
}