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

考虑下面这个算法,它求的是数值数组中大小最接近的两个元素的差。
可对比看下求数组中两个元素差的最大值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 ( a < b ),然后依次取剩下的元素,将新元素 c 与 a、b 比较,如果 c ∉ (a,b),那么直接舍弃 c 即可;如果 c ∈ (a,b),再根据 c 和 (a+b)/2 的大小来更新 a 或 b。

时间复杂度为O(n)

/**
 * 乱序数组找出其中最接近的两个数,并输出两个数的差值
 * 首先分别找出最小值a和最大值b
 * 然后依次遍历数组元素,将新元素 c 与 a、b 比较,
 * 如果 c ∉ (a,b),那么直接舍弃 c 即可;
 * 如果 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;
        //a最小值
        //b最大值
        a = A[0];
        b = A[0];
        for (int i = 0; i < A.length; i++) {
         if (A[i]>b){
             b = A[i];
         }
        }
        for (int i = 0; i < A.length; i++) {
            if (A[i]<a){
                a = A[i];
            }
        }

        for(int i=0;i<A.length;i++){
            c=A[i];
            if(c>=b||c<=a){//(a,b)之外的数字,第一次没有用因为a和b是min和max,但是后面交换之后会有用的
                continue;
            }
            if(2*c>(a+b)){
                a=c;
            }
            else{
                b=c;
            }
        }
        return b-a;
    }

    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));
    }
}

猜你喜欢

转载自blog.csdn.net/fkyyly/article/details/84231390
今日推荐