原文:https://lwebapp.com/zh/post/l...
问题
给你一个长度为 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
中的每个元素呈现 一次 或 两次
原文:https://lwebapp.com/zh/post/l...
更多刷题笔记:https://lwebapp.com/zh/tag/le...
解法一
思路:
利用 Set
值惟一的个性,一直向一个空的 Set
外面增加 nums
中的数字,再应用 set.add
办法,通过获取 set
长度是否减少来判断是否有反复数字呈现。
代码:
/** * @param {number[]} nums * @return {number[]} */var findDuplicates = function(nums) { const set = new Set() // 惟一值测验 const result = [] // 后果数组 nums.forEach(n => { const preSize = set.size // 应用 set.add 办法,通过获取 set 长度是否减少来判断是否有反复数字呈现 set.add(n) // 发现反复数字 if(preSize === set.size){ result.push(n) } }) return result};
解法二
思路:
遍历整个数组,将每一个数字视为数组地位信息,再将每一个地位对应的数字反转为正数,相当于做一个标识,表明这个数字对应的地位,曾经有数字占用了,下一次再遇到这个数字如果发现是正数就表明曾经呈现过。
比方 [4,3,2,7,8,2,3,1]
,走到第一个 2
的时候,翻转地位为 1
的数字 3
为 -3
,走到下一个 2
的时候,就能发现地位为 1
的数字为 -3
, 曾经被翻转过了,表明数字 2
呈现了两次。
代码:
/** * @param {number[]} nums * @return {number[]} */var findDuplicates = function(nums) { let result = []; for (let i = 0; i < nums.length; i++) { let num = Math.abs(nums[i]); if (nums[num - 1] > 0) { /** 把数字翻转为正数的目标是,做一个标识,表明这个数字对应的地位,曾经有数字占用了,下一次再遇到这个数字如果发现是正数就表明曾经呈现过 比方[4,3,2,7,8,2,3,1] 走到第一个2的时候,地位为1的数字为3,将3翻转为-3,走到下一个2的时候,翻转3的时候发现曾经被翻转过了 */ nums[num - 1] *= -1; } else { result.push(num); } } return result;};
参考
- LeetCode笔记:数组中反复的数据
- 442. 数组中反复的数据