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

相关推荐
君义_noip11 小时前
信息学奥赛一本通 2134:【25CSPS提高组】道路修复 | 洛谷 P14362 [CSP-S 2025] 道路修复
c++·算法·图论·信息学奥赛·csp-s
kaikaile199511 小时前
基于拥挤距离的多目标粒子群优化算法(MO-PSO-CD)详解
数据结构·算法
不忘不弃11 小时前
求两组数的平均值
数据结构·算法
leaves falling11 小时前
迭代实现 斐波那契数列
数据结构·算法
珂朵莉MM11 小时前
全球校园人工智能算法精英大赛-产业命题赛-算法巅峰赛 2025年度画像
java·人工智能·算法·机器人
Morwit11 小时前
*【力扣hot100】 647. 回文子串
c++·算法·leetcode
DonnyCoy11 小时前
Android性能之数据结构
数据结构
天赐学c语言11 小时前
1.7 - 删除排序链表中的重要元素II && 哈希冲突常用解决冲突方法
数据结构·c++·链表·哈希算法·leecode
tobias.b12 小时前
408真题解析-2009-13-计组-浮点数加减运算
算法·计算机考研·408考研·408真题
菜鸟233号12 小时前
力扣96 不同的二叉搜索树 java实现
java·数据结构·算法·leetcode