三元组的最小距离问题|数据结构常见小题05

欢迎大家在评论区分享自己遇到的算法题目,小编看到的话就会进行回复!

问题:

三元组(a,b,c), a b c分别取自S1 S2 S3(三个升序序列)
三元组的距离公式D=|a-b|+|b-c|+|c-a|
求所有三元组中,距离最小的三元组,及其距离

分析:

本质上是最大元素与最小元素距离的二倍,计算距离极值即可

算法:

算法1

最笨的方法,但是简单容易接收。
使用三层循环求出所有距离,找出最小距离

int findMinDistance1(int S1[], int l1, int S2[], int l2, int S3[], int l3){
    int minCombin[3] = {S1[0], S2[0], S3[0]}, minDistance, D;
    minDistance = Distance(S1[0], S2[0], S3[0]);
    for(int i=0;i<l1;i++){
        for(int j=0;j<l2;j++){
            for(int k=0;k<l3;k++){
                D = Distance(S1[i], S2[j], S3[k]);
                if(minDistance>D){
                    minDistance = D;
                    minCombin[0] = S1[i];
                    minCombin[1] = S2[j];
                    minCombin[2] = S3[k];
                }
            }
        }
    }
    cout <<'('<<minCombin[0]<<','<<minCombin[1]<<','<<minCombin[2]<<')'<<endl;
    return minDistance;
}

算法2

最小项移位对比的方法,时间复杂度O(n)
两个要点:

  1. 找到三个元素中最小的那个
  2. 每次循环只改变(增大)最小元素的值
int findMinDistance2(int S1[], int l1, int S2[], int l2, int S3[], int l3){
    int a, b, c;
    a = S1[0];
    b = S2[0];
    c = S3[0];
    int i = 0, j = 0, k = 0;
    int minD = Distance(S1[0], S2[0], S3[0]),D;
    while(i<l1 || j<l2 || k<l3){
        D = Distance(S1[i], S2[j], S3[k]);
        if(D<minD){
            minD = D;
        }
        if(S1[i]<=S2[j] && S1[i]<=S3[k])
            i++;
        else if(S2[j]<=S3[k] && S2[j]<=S1[i])
            j++;
        else k++;
    }
    return minD;
}

测试

int main(){
    int S1[3] = {-1,0,9}, 
        S2[4]={-25,-10,10,11}, 
        S3[5]={2,9,17,30,41};
    int minD1 = findMinDistance1(S1,3,S2,4,S3,5);
    int minD2 = findMinDistance2(S1,3,S2,4,S3,5);
    cout<<minD1<<endl;
    cout<<minD2<<endl;
    return 0;
 }

结果:
(9,10,9)
2
2


小结

第二种算法带一些数学思维,在以后的应用中常常会出现在小细节处。

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值