力扣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 解法(易理解、易实现),再进阶学习双指针思路。

相关推荐
Wect5 小时前
LeetCode 130. 被围绕的区域:两种解法详解(BFS/DFS)
前端·算法·typescript
NAGNIP16 小时前
一文搞懂深度学习中的通用逼近定理!
人工智能·算法·面试
颜酱1 天前
单调栈:从模板到实战
javascript·后端·算法
CoovallyAIHub1 天前
仿生学突破:SILD模型如何让无人机在电力线迷宫中发现“隐形威胁”
深度学习·算法·计算机视觉
CoovallyAIHub1 天前
从春晚机器人到零样本革命:YOLO26-Pose姿态估计实战指南
深度学习·算法·计算机视觉
CoovallyAIHub1 天前
Le-DETR:省80%预训练数据,这个实时检测Transformer刷新SOTA|Georgia Tech & 北交大
深度学习·算法·计算机视觉
CoovallyAIHub1 天前
强化学习凭什么比监督学习更聪明?RL的“聪明”并非来自算法,而是因为它学会了“挑食”
深度学习·算法·计算机视觉
CoovallyAIHub1 天前
YOLO-IOD深度解析:打破实时增量目标检测的三重知识冲突
深度学习·算法·计算机视觉
NAGNIP2 天前
轻松搞懂全连接神经网络结构!
人工智能·算法·面试
NAGNIP2 天前
一文搞懂激活函数!
算法·面试