多种解法全解析——力扣217. 存在重复元素

力扣217. 存在重复元素


【LeetCode题解】217. 存在重复元素(多种解法全解析)

一、题目描述

给定一个整数数组 nums,判断数组中是否存在重复元素:

  • 如果任一值在数组中至少出现两次,返回 true
  • 如果数组中每个元素都不同,返回 false

示例

示例 1:

复制代码
输入: nums = [1,2,3,1]
输出: true

示例 2:

复制代码
输入: nums = [1,2,3,4]
输出: false

示例 3:

复制代码
输入: nums = [1,1,1,3,3,4,3,2,4,2]
输出: true

提示

  • 1 <= nums.length <= 10^5
  • -10^9 <= nums[i] <= 10^9

二、解法思路

这道题的核心就是:检查数组中是否有重复元素

下面我会从暴力法到高效解法,依次介绍多种方法。


三、解法一:暴力枚举(双重循环)

这是最直观的解法,对每个元素都去和后续所有元素比较,如果有相等的就返回 true

  • 时间复杂度:O(n^2),最坏情况下要比较所有元素对。
  • 空间复杂度:O(1),没有额外开销。

代码实现

java 复制代码
class Solution {
    public boolean containsDuplicate(int[] nums) {
        for (int i = 0; i < nums.length; i++) {
            for (int j = i + 1; j < nums.length; j++) {
                if (nums[i] == nums[j]) {
                    return true;
                }
            }
        }
        return false;
    }
}

四、解法二:排序后扫描

先对数组排序,重复元素一定会出现在相邻位置。只要检查相邻是否相等即可。

  • 时间复杂度:O(n log n),排序的时间消耗。
  • 空间复杂度:取决于排序算法,通常是 O(1)O(log n)

代码实现

java 复制代码
import java.util.Arrays;

class Solution {
    public boolean containsDuplicate(int[] nums) {
        Arrays.sort(nums);
        for (int i = 1; i < nums.length; i++) {
            if (nums[i] == nums[i - 1]) {
                return true;
            }
        }
        return false;
    }
}

五、解法三:哈希集合(HashSet)

利用哈希集合的特性:

  • 插入时如果发现元素已经存在,则说明有重复。

这是最常用的方法,效率也最高。

  • 时间复杂度:O(n),遍历一次数组。
  • 空间复杂度:O(n),哈希集合的存储开销。

代码实现

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

class Solution {
    public boolean containsDuplicate(int[] nums) {
        HashSet<Integer> seen = new HashSet<>();
        for (int num : nums) {
            if (seen.contains(num)) {
                return true;
            }
            seen.add(num);
        }
        return false;
    }
}

六、解法四:哈希表(HashMap)

与 HashSet 类似,用哈希表统计每个元素的出现次数,如果某个元素超过 1,则返回 true

  • 时间复杂度:O(n)
  • 空间复杂度:O(n)

代码实现

java 复制代码
import java.util.HashMap;

class Solution {
    public boolean containsDuplicate(int[] nums) {
        HashMap<Integer, Integer> map = new HashMap<>();
        for (int num : nums) {
            if (map.containsKey(num)) {
                return true;
            }
            map.put(num, 1);
        }
        return false;
    }
}

七、解法五:流式写法(Java 8+)

如果使用 Java 8 及以上版本,可以利用流的去重特性。

通过比较去重前后的长度是否相等,判断是否有重复元素。

  • 时间复杂度:O(n)
  • 空间复杂度:O(n)

代码实现

java 复制代码
import java.util.Arrays;

class Solution {
    public boolean containsDuplicate(int[] nums) {
        return Arrays.stream(nums).distinct().count() < nums.length;
    }
}

八、总结

方法 时间复杂度 空间复杂度 适用场景
暴力枚举 O(n^2) O(1) 数据规模很小
排序后扫描 O(n log n) O(1)~O(log n) 中等规模,允许排序
哈希集合 O(n) O(n) 高效通用,推荐
哈希表计数 O(n) O(n) 适合需要统计频率
流式写法 O(n) O(n) 简洁优雅,但开销稍大

其中 哈希集合解法 是最常用、最推荐的方案。


相关推荐
金宗汉2 分钟前
《宇宙递归拓扑学:基于自指性与拓扑流形的无限逼近模型》
大数据·人工智能·笔记·算法·观察者模式
YY_TJJ2 小时前
算法题——贪心算法
算法·贪心算法
C++ 老炮儿的技术栈2 小时前
include″″与includ<>的区别
c语言·开发语言·c++·算法·visual studio
RainbowC02 小时前
GapBuffer高效标记管理算法
android·算法
liu****2 小时前
10.queue的模拟实现
开发语言·数据结构·c++·算法
mit6.8243 小时前
10.17 枚举中间|图论
算法
小龙报3 小时前
《彻底理解C语言指针全攻略(6)-- qsort、sizeof和strlen》
c语言·开发语言·职场和发展·创业创新·学习方法·业界资讯·visual studio
让我们一起加油好吗3 小时前
【基础算法】01BFS
数据结构·c++·算法·bfs·01bfs
孤狼灬笑3 小时前
机器学习十大经典算法解析与对比
人工智能·算法·机器学习
1白天的黑夜14 小时前
递归-24.两两交换链表中的节点-力扣(LeetCode)
数据结构·c++·leetcode·链表·递归