如何快速高效的比较两个整型数组差异

现在存在两个数组,如何高效快速的找出一个数组有另外一个数组不存在的数。

有朋友说他在一次面试中面试官问:现在有两个数组 a,b,如何快速高效的找出数组b中有数组a中不存在的数。

我们来分析一下这个问题
我们最容易想到的就是两个循环,外层循环数组b,里层循环数组a,如果数组b中的数不存在就记录下来。这样确实可以找到想要的数,但是时间复杂度是O(a.length*b.length), 当数组长度比较大时,不仅效率低,还会导致内存不够用或者内存泄露。显然这个不是我们想要的答案。
中国古代就有一种叫 “ 分而治之 ” 的思想,在皇权时代,皇帝将权利下发给一级官员,一级官员将权利下发给二级官员 如此往下,然后做事的时候,上层官员向下逐层发送命令,下层做完后向上层逐层反馈结果。这样的结果就是效率高,准确性高。
分治思想在算法领域应用很多,堆排序,快速排序,跳表等都是常见的案例。

废话不多说,我直接粘代码吧

import java.util.ArrayList;
import java.util.HashMap;

public class quickSearchArray {

    public static void main(String[] args) {
        int [] a =new int[100000];
        int [] b =new int[99999];
        int k=0;
        for(int i=0;i<100000;i++){//初始化数组,因为数组比较大我就随便给数组赋值了
            a[i]=i+1;
            if(i+1!=30&&i+1!=56&&i+1!=500){
                b[k]=i+1;
                k++;
            }
        }
    long l1=System.currentTimeMillis();
        //第一种方式直接双重循环
       /*for(int i=0;i<a.length;i++){
            int result =0;
            for(int j=0;j<b.length;j++){
                if(a[i]==b[j]){
                    result=1;
                }
            }
            if(result==0){
                System.out.println("不包含的数:"+a[i]) ;
            }
        }*/
       //第二种将数组划分成100个小数组,然后再找出不存在的数
       /*int m=1001 ;
        int n=100;
        ArrayList<ArrayList<Integer>> towArray=new ArrayList<ArrayList<Integer>>();
        for(int i=0;i<m;i++){
            towArray.add(new ArrayList<Integer>());
        }
        for(int i=0;i<b.length;i++){
            int index =b[i]/m;
            towArray.get(index).add(b[i]);


           // System.out.println(b[i]+":"+index);
        }
        for(int i=0;i<a.length;i++){
            int index =a[i]/m;

            //System.out.println("不包含的数:"+index);
            if(!towArray.get(index).contains(a[i])){
                System.out.println("不包含的数:"+a[i]);
            }
        }

        */
       //第三种 构建hashMap
        int m=10;
        HashMap<Integer,ArrayList<Integer>> map=new HashMap<Integer,ArrayList<Integer>>();
        for(int i=0;i<b.length;i++){
            int index =b[i]/m;
            if(!map.containsKey(index)) {
                map.put(index, new ArrayList<Integer>());
            }
            map.get(index).add(b[i]);

        }
        for(int i=0;i<a.length;i++){
            int index =a[i]/m;

            //System.out.println("不包含的数:"+index);
            if(!map.get(index).contains(a[i])){
                System.out.println("不包含的数:"+a[i]);
            }
        }

        System.out.println("time:"+(System.currentTimeMillis()-l1));
    }

}

第一种直接二重循环比较,第二种是将数组划分成100个小数组(可以根据实际调)构建二维数组,第三种和第二种类似,用hash代替二维数组。

根据控制台的输出结果可以发现数组越大,第二,三种效率高出了很多倍。

在实际应用中我们可以将第二种的数组维度扩展到 三围 四维,数组划分条件设置成合适的,第三种的hash的key设计成合适的,尽量使每个小块比较均匀。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值