【leetcode】442. 数组中重复的数据

🚅【leetcode】442. 数组中重复的数据


在这里插入图片描述

🚀题目

leetcode原题链接

给你一个长度为 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]
输出:[]

提示:
n == nums.length
1 <= n <= 105
1 <= nums[i] <= n
nums 中的每个元素出现 一次 或 两次

💥leetcode代码模板

/**
 * @param {number[]} nums
 * @return {number[]}
 */
var findDuplicates = function(nums) {

};

🚀思路

在这里插入图片描述
leetcode官方还是太好了,把关键词都加粗了,生怕我这种初级选手没有思路。

注意题目中加粗的文字:一次或两次

数组的长度为n,数字的范围为[1,n],数字又只能出现一次或两次,那么思路就有了:

数组本身具有的东西就是索引,除非你这个数字出现了两次,否则索引又刚好可以和数字一一对应。

所以我们可以找出那些不是一一对应的数字,添加到结果数组就好了。

现在问题来了,怎么找而又指利用常量而外空间呢?

我们得标记出现过的数字,当再次遇到它时就说明它出现了两次!这里介绍两种标记方式:

1️⃣交换元素

  • 当遇到一个nums[i]发现nums[i] - 1 !== i,那就把它挪到它与索引对应的位置,例如1应该对应索引0,4对应索引3。
  • 当再次遇到该数字,检查一下它对应索引位置处的值是否等于它,是的话说明重复,添加到结果中。
  • 由于我们交换了元素,所以有可能导致重复判断一个数字,所以要对结果进行去重。

2️⃣不交换元素
-注意到题目中数字都是正数,那么我们可以把出现过的数字对应的索引处的值取反变为负数,从而进行标记。

  • 遍历数组,如果发现当前数字的绝对值对应的索引处的值小于0,就把该值加入结果,否则就标记对应索引位置的值。
  • 由于我们没有交换元素,每个元素只会遍历一次,因此不用去重。

💻代码

在这里插入图片描述

var findDuplicates = function(nums) {
    let ans = new Set()
    function wrap(i , j){
        let temp = nums[i]
        nums[i] = nums[j]
        nums[j] = temp
    }
    for(let i = 0 ; i < nums.length ; i++){
        let j = nums[i] - 1
        if(i !== j){
            if(nums[i] === nums[j]){
                ans.add(nums[i])
            }else{
                wrap(i , j)
                i-- // 交换过来的数字还没判断过
            }
        }
    }
    return Array.from(ans)
};
var findDuplicates = function(nums) {
    let ans = []
    let len = nums.length
    for(let i = 0 ; i < nums.length ; i++){
        let j = Math.abs(nums[i]) - 1
        if(nums[j] < 0) ans.push(Math.abs(nums[i]))
        else nums[j] *= -1
    }
    return ans
};

🍪总结

这道题主要是学习这种原地标记的思想。

我 是 c o n e r , 请 别 关 注 我 的 专 栏 , 本 系 列 文 章 为 个 人 刷 题 记 录 ( 偷 偷 自 己 卷 🤤 ) : \textcolor{green}{我是coner,请别关注我的专栏,本系列文章为个人刷题记录(偷偷自己卷🤤):} coner🤤leetcode题解js

每 天 更 新 3 道 l e e t c o d e 题 目 的 j s 题 解 🚀 🚀 🚀 \textcolor{green}{每天更新3道leetcode题目的js题解🚀🚀🚀} 3leetcodejs🚀🚀🚀

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端corner

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值