力扣349. 两个数组的交集

题干要求

给定两个整数数组 nums1nums2,返回它们的交集。输出结果中的每个元素一定是唯一的,不考虑输出结果的顺序。

二、两种核心解法(面试高频,直接 AC)

解法 1:HashSet 最优解(推荐!线性时间,新手首选)

核心思路

利用 HashSet「自动去重」和「O (1) 快速查找」的特性:

  1. 把其中一个数组存入 HashSet(自动去重,减少查找次数);
  2. 遍历另一个数组,判断元素是否在 HashSet 中存在;
  3. 用另一个 HashSet 存储结果(避免遍历数组时出现重复元素);
  4. 最后将结果 HashSet 转为数组。

代码实现:

java 复制代码
import java.util.HashSet;
import java.util.Set;

public class Solution {
    public int[] intersection(int[] nums1, int[] nums2) {
        // 用HashSet存nums1,自动去重
        Set<Integer> set = new HashSet<>();
        for (int num : nums1) {
            set.add(num);
        }
        
        // 存结果,避免重复
        Set<Integer> resSet = new HashSet<>();
        for (int num : nums2) {
            // 存在即交集元素
            if (set.contains(num)) {
                resSet.add(num);
            }
        }
        
        // Set转数组,简洁写法
        return resSet.stream().mapToInt(Integer::intValue).toArray();
    }
}
复杂度分析
  • 时间:O (m + n)(m、n 为数组长度,两次线性遍历,查找是 O (1));
  • 空间:O (min (m, n))(仅存储较短数组的元素,优化空间)

解法 2:排序 + 双指针(省空间,适配空间限制场景)

核心思路
  1. 两个数组先排序,利用排序后元素有序的特性;
  2. 双指针分别从数组开头出发,对比元素:
    • 元素相等 → 加入结果(需跳过后续重复元素,保证唯一);
    • 元素不等 → 小的指针后移(有序数组中,小元素不可能是交集)。
代码实现
java 复制代码
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Solution {
    public int[] intersection(int[] nums1, int[] nums2) {
        // 排序预处理
        Arrays.sort(nums1);
        Arrays.sort(nums2);
        
        int i = 0, j = 0;
        List<Integer> resList = new ArrayList<>();
        while (i < nums1.length && j < nums2.length) {
            if (nums1[i] == nums2[j]) {
                // 加入结果,同时跳过重复元素(保证唯一)
                resList.add(nums1[i]);
                // 跳过nums1的重复元素
                while (i < nums1.length - 1 && nums1[i] == nums1[i + 1]) {
                    i++;
                }
                // 跳过nums2的重复元素
                while (j < nums2.length - 1 && nums2[j] == nums2[j + 1]) {
                    j++;
                }
                // 双指针同时后移
                i++;
                j++;
            } else if (nums1[i] < nums2[j]) {
                i++;
            } else {
                j++;
            }
        }
        
        // List转数组
        return resList.stream().mapToInt(Integer::intValue).toArray();
    }
}
复杂度分析
  • 时间:O (m logm + n logn)(排序占主要耗时,双指针遍历是 O (m + n));
  • 空间:O (1)(忽略排序系统栈空间,仅用 List 存结果,题目不计数组输出空间)。

总结

这道题的核心是「去重 + 找共同元素」,两种解法覆盖不同场景,新手优先掌握 HashSet 解法(易理解、易实现),再进阶学习双指针思路。

相关推荐
北域码匠23 分钟前
高通滤波算法深度解析(High-Pass Filter)
stm32·算法·c#·数字信号处理·嵌入式开发·滤波算法·高通滤波
指掀涛澜天下惊1 小时前
强化学习进阶篇八 策略梯度算法
深度学习·学习·算法·强化学习
乌萨奇也要立志学C++1 小时前
【洛谷】kmp算法
开发语言·算法
禹凕1 小时前
Dijkstra算法详解与应用
python·算法
YaraMemo2 小时前
元启发式算法框架
人工智能·算法·5g·信息与通信·启发式算法·信号处理
weixin_307779132 小时前
一维无粘 Burgers 方程的激波形成问题:MacCormack 格式求解
c++·算法·matlab
HugoStudio_SWAN3 小时前
洛谷 B4500 / B4449 / B3843 凯撒密码、密码强度与密码合规——加密与安全的三道门
c++·学习·程序人生·算法·安全
枫叶林FYL4 小时前
【群体智能集群控制工程实践】第3章 一致性协同算法
算法
禹凕4 小时前
滑动窗口算法实战指南
python·算法
DisonTangor4 小时前
【腾讯混元雪耻归来】 Hy4 preview:770B 参数 MoE 旗舰模型,1M 上下文全面开源
人工智能·算法·开源·aigc·腾讯云·腾讯云ai代码助手