Evan Wang
Evan WangFrontEnd Developer
  • Evan Wang
    Evan WangFrontEnd Developer
  • 前端相关
  • 算法题
  • 日常笔记
  • Chat With AI

两数之和
两数相加
无重复字符的最长子串
最长回文子串
盛水最多的容器
三数之和
电话号码的字母组合
有效括号
合并两个有序链表
括号生成
下一个排列
搜索旋转排序数组
在排序数组中查找元素的第一个和最后一个位置
删除链表的倒数第n个节点
组合总和
全排列
旋转图像
字母异位词分组
最大子数组合
跳跃游戏
反转链表
反转链表2
合并区间
最小路径和
编辑距离
颜色分类
爬楼梯
组合
子集
不同的二叉搜索树
验证二叉搜索树
对称二叉树
二叉树的层序遍历
二叉树的最大深度
从前序与中序遍历序列构造二叉树
只出现一次的数字
二叉树展开为链表
最长连续序列
单词拆分
环形链表
环形链表2
排序链表
相交链表
乘积最大子数组
最小栈
多数元素
打家劫舍
数组中重复的数据
二叉树的中序遍历
卖股票的最佳时机
数组中的第K个最大元素

  1. Articles
  1. More
  2. 47-数组中重复的数据.mdx
目录
题目方法一代码实现方法二代码实现
1163 字
约 3 分钟
更新于 2026/08/20

数组中重复的数据

题目

给你一个长度为 n 的整数数组 nums ,其中 nums 的所有整数都在范围 [1, n] 内,且每个整数出现 一次 或 两次 。请你找出所有出现 两次 的整数,并以数组形式返回。
你必须设计并实现一个时间复杂度为 O(n) 且仅使用常量额外空间的算法解决此问题。

示例 1:

输入:nums = [4,3,2,7,8,2,3,1]
输出:[2,3]

示例 2:

输入:nums = [1,1,2]
输出:[1]

示例 3:

输入:nums = [1]
输出:[]

方法一

循环给定数组,利用 map 建立映射关系,key: 当前元素,value: 当前元素在数组中出现的次数。 最后遍历 map,过滤调不符合提议的,返回正确结果。

代码实现

/**
 * @param {number[]} arr
 * @return {number[]}
 */
const findDuplicates = (arr) => {
    const result = []
    const map = new Map()
    for (let i = 0; i < arr.length; i++) {
        if (map.get(arr[i])) {
            map.set(arr[i], map.get(arr[i]) + 1)
        } else {
            map.set(arr[i], 1)
        }
    }
    map.forEach((item, key) => {
        if (item > 1) {
            result.push(key)
        }
    })
    return result
}

方法二

创建一个新数组 arr,长度和给定数组 nums 长度相同,由于 nums 中所有元素都在 [1, n] 中,所以下标不会越界,
循环数组,以当前元素 i 作为 arr 的下标,

  • 如果能访问到 arr[i],说明 nums[i] 出现了 2次以上,存入结果集中,
  • 如果不能访问到 arr[i],说明当前循环是第一次遇到 num[i], 执行 arr[i] = 1 后,继续循环.

代码实现

const findDuplicates = (nums) => {
    const arr = new Array(nums.length).fill(0)
    const result = []
 
    for (let i = 0; i < nums.length; i++) {
        if (!arr[nums[i]]) {
            arr[nums[i]] = 1
        } else {
            result.push(nums[i])
        }
    }
    return result
}