You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

百万级整数List查找重复元素的最优时间复杂度实现方案咨询

高效找出百万级整数列表中的重复元素

嗨,这个场景太典型了!双循环的O(n²)复杂度在百万条数据面前完全是灾难——光是计算量就到了10¹²级别,根本跑不完。下面给你几个工业级的高效方案,按实用性排序:

1. 哈希集合(HashSet)法:时间O(n),空间O(n)

这是最常用的最优时间复杂度方案,利用哈希表的O(1)查找特性:

  • 遍历列表时,每次检查当前元素是否在集合中
  • 如果存在,说明是重复元素,直接收集
  • 如果不存在,把元素加入集合

Java示例代码:

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

public class DuplicateFinder {
    public static List<Integer> findDuplicates(List<Integer> nums) {
        HashSet<Integer> seen = new HashSet<>();
        List<Integer> duplicates = new ArrayList<>();
        for (int num : nums) {
            if (!seen.add(num)) { // add返回false说明元素已存在
                duplicates.add(num);
            }
        }
        return duplicates;
    }
}

Python示例代码:

def find_duplicates(nums):
    seen = set()
    duplicates = []
    for num in nums:
        if num in seen:
            duplicates.append(num)
        else:
            seen.add(num)
    return duplicates

注意:如果需要去重后的重复元素列表(比如重复多次只保留一次),可以用另一个集合存重复元素,最后转成列表。

2. 排序后遍历:时间O(n log n),空间O(1)(原地排序)

如果内存比较紧张,不想用额外的O(n)空间,可以先排序再遍历:

  • 排序后重复元素会相邻,只需要比较当前元素和前一个元素是否相等
  • 优点是空间开销极小,缺点是会改变原列表的顺序,且排序的O(n log n)比哈希法慢一点,但百万数据依然很快

Java示例代码:

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class DuplicateFinder {
    public static List<Integer> findDuplicates(List<Integer> nums) {
        Collections.sort(nums);
        List<Integer> duplicates = new ArrayList<>();
        for (int i = 1; i < nums.size(); i++) {
            if (nums.get(i).equals(nums.get(i-1)) && 
                (duplicates.isEmpty() || !nums.get(i).equals(duplicates.get(duplicates.size()-1)))) {
                duplicates.add(nums.get(i));
            }
        }
        return duplicates;
    }
}

Python示例代码:

def find_duplicates(nums):
    nums.sort()
    duplicates = []
    for i in range(1, len(nums)):
        if nums[i] == nums[i-1] and (not duplicates or nums[i] != duplicates[-1]):
            duplicates.append(nums[i])
    return duplicates

3. 计数数组法:时间O(n),空间O(k)(k为整数范围)

如果已知整数的范围(比如所有数都是0~1000000),可以用计数数组直接统计出现次数,效率比哈希集合还高:

  • 初始化一个长度为max_num+1的数组,初始值为0
  • 遍历列表,每个元素对应的计数加1
  • 最后遍历计数数组,收集计数>=2的元素

Java示例代码:

import java.util.ArrayList;
import java.util.List;

public class DuplicateFinder {
    public static List<Integer> findDuplicates(List<Integer> nums) {
        int max = Integer.MIN_VALUE;
        for (int num : nums) {
            if (num > max) max = num;
        }
        int[] count = new int[max + 1];
        List<Integer> duplicates = new ArrayList<>();
        for (int num : nums) {
            count[num]++;
        }
        for (int i = 0; i <= max; i++) {
            if (count[i] >= 2) {
                duplicates.add(i);
            }
        }
        return duplicates;
    }
}

方案选择建议

  • 优先选哈希集合法:时间最优,实现简单,百万数据的内存开销完全可控(整数占4字节的话,百万个元素也就4MB左右)
  • 内存紧张选排序法:牺牲一点时间换空间
  • 整数范围明确选计数数组法:速度最快,空间开销最小

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:52:24