数据结构算法题/求数组中大小最接近的两个元素的差

考虑下面这个算法,它求的是数值数组中大小最接近的两个元素的差。
可对比看下求数组中两个元素差的最大值https://blog.csdn.net/fkyyly/article/details/83930343

算法: MinDistance(A[0..n-1])
                //输入:数字数组 A[0..n-1]
                //输出:数组中两个大小相差最少的元素的差值
                dmin <- ∞
                for i <- 0 to n-1 do
                    for j <- 0 to n-1 do
                        if i≠j and |A[[i]-A[j]| < dmin
                            dmin <- |A[i]-A[j]|
                return dmin

尽可能改进该算法(如果有必要,完全可以抛弃该算法;否则,请改进该算法)

  原算法遍历每一个元素对,时间复杂度为 O(n²)。这其中有一半的元素对是重复比较的。且在已知 a < b < c 而比较过了 a、b 的差的情况下,没必要再比较 a 和 c 的差。

  改进该算法的思想时,先取前两个元素,小的为a,大的为b,result为b-a的值,然后依次取剩下的元素,将新元素 c 与 a、b 比较,存在如下三种情况

(1)如果 c ∈ (a,b),c在a和b之间,再根据 c 和 (a+b)/2 的大小来更新 a 或 b。

(2)如果 c<a<b,判断b-a与a-c的值大小,如果a-c<b-a那么调整ab的结果b=a,a=c

(3)如果a<b<c,判断c-b与b-a的值大小,如果c-b<b-a那么调整ab的结果a=b,b=c

时间复杂度为O(n)

/**
 * 乱序数组找出其中最接近的两个数,并输出两个数的差值
 * 首先分别找出最小值a和最大值b
 * 然后依次遍历数组元素,将新元素 c 与 a、b 比较,
 * 如果 c ∈ (a,b),再根据 c 和 (a+b)/2 的大小来更新 a 或 b
 * 具体的是如果c>(a+b)/2 则a=c
 * 如果c<(a+b)/2 则b=c
 */
public class ClosestTwoDataMinus {
     int MinDistance(int A[])
    {
        int a,b,c,result;
        a = A[0];
        b = A[1];
        //保证b大a小
        if(a>b){
            result=a;
            a=b;
            b=result;
        }
        result = b-a;
        for(int i=2;i<A.length;i++){
            c=A[i];
            // c在中间
            if(c>=a && c<=b){//(a,b)之外的数字,第一次没有用因为a和b是min和max,但是后面交换之后会有用的
                if(2*c>=(a+b)){
                    a=c;
                } else{
                    b=c;
                }
            }else if (c<a){//c在左边
                int ba = b-a;
                int ac = a-c;
                if(ac<ba){
                    b = a;
                    a = c;
                }
            }else {//c在右边
                int ba = b-a;
                int cb = c-b;
                if(cb<ba){
                    a = b;
                    b = c;
                }
            }
            result = b - a;
        }
        System.out.println("b=" + b);
        System.out.println("a=" + a);
        return result;
    }

    public static void main(String[] args) {
        ClosestTwoDataMinus closestTwoDataMinus = new ClosestTwoDataMinus();
        int[] A = {-1, 5, 1, 100, 105, 107};
//        int[] A = {1, 4, 5};
        System.out.println(closestTwoDataMinus.MinDistance(A));
    }
}
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值