You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Java中逐元素检查两个数组是否存在至少一个公共元素的高效方法

高效检查两个Java数组是否存在至少一个公共元素的方法

嘿,这个问题问得很实在!你现在用的循环遍历找公共元素的方法在小数据量下没问题,但当数组规模变大时,确实有更高效的方案可以用,我给你梳理几种常用的优化思路:

方法一:利用HashSet(推荐给大多数场景)

HashSet的核心优势是平均O(1)时间复杂度的查找操作,我们可以把其中一个数组的元素存入HashSet,再遍历另一个数组检查元素是否存在,整体时间复杂度是O(n+m),比双重循环的O(n*m)高效太多。

代码示例:

import java.util.HashSet;
import java.util.Set;

public class CommonElementChecker {
    public static boolean hasCommonElement(int[] arr1, int[] arr2) {
        Set<Integer> elementSet = new HashSet<>();
        // 先将第一个数组的元素存入集合(自动去重,不影响结果判断)
        for (int num : arr1) {
            elementSet.add(num);
        }
        // 遍历第二个数组,一旦找到公共元素就立即返回
        for (int num : arr2) {
            if (elementSet.contains(num)) {
                return true;
            }
        }
        return false;
    }

    public static void main(String[] args) {
        int[] arrA = {1, 2, 2, 3};
        int[] arrB = {2, 3, 5, 6};
        int[] arrC = {5, 2, 1, 5};
        
        System.out.println(hasCommonElement(arrA, arrB)); // 输出 false
        System.out.println(hasCommonElement(arrA, arrC)); // 输出 true
    }
}

小技巧:如果其中一个数组特别小,优先把小的数组存入HashSet,这样能减少内存占用和插入集合的时间。

方法二:排序后双指针遍历(适合内存受限场景)

如果你的运行环境内存紧张,不想用额外的集合空间,可以先对两个数组排序,再用双指针遍历查找,整体时间复杂度是O(n log n + m log m),空间复杂度为O(1)(Java的Arrays.sort是原地排序)。

代码示例:

import java.util.Arrays;

public class CommonElementChecker {
    public static boolean hasCommonElement(int[] arr1, int[] arr2) {
        Arrays.sort(arr1);
        Arrays.sort(arr2);
        
        int i = 0, j = 0;
        // 双指针同步移动,寻找相等元素
        while (i < arr1.length && j < arr2.length) {
            if (arr1[i] == arr2[j]) {
                return true;
            } else if (arr1[i] < arr2[j]) {
                i++;
            } else {
                j++;
            }
        }
        return false;
    }

    public static void main(String[] args) {
        int[] arrA = {1, 2, 2, 3};
        int[] arrB = {2, 3, 5, 6};
        int[] arrC = {5, 2, 1, 5};
        
        System.out.println(hasCommonElement(arrA, arrB)); // 输出 false
        System.out.println(hasCommonElement(arrA, arrC)); // 输出 true
    }
}

这种方法适合数组本身接近有序的场景,排序的开销会大幅降低。

和你当前方法的对比

你现在用的单循环+线性查找(或双重循环)本质是O(n*m)的时间复杂度,比如两个各有1000个元素的数组,双重循环要执行100万次操作;而HashSet方法只需要2000次左右的操作,数据量越大,性能差距越明显。

额外优化小提示

  • 如果数组是基本类型(比如int),使用HashSet<Integer>会有自动装箱的开销,追求极致性能的话,可以用第三方库的TIntHashSet(比如Apache Commons Collections),避免装箱拆箱的损耗。
  • 不管用哪种方法,一旦找到第一个公共元素就立即终止遍历,这一点你已经做得很好了,能减少不必要的计算。

内容的提问来源于stack exchange,提问作者blah_crusader

火山引擎 最新活动