题目描述
集合 s 包含从 1 到 n 的整数。不幸的是,因为数据错误,导致集合里面某一个数字复制了成了集合里面的另外一个数字的值,导致集合 丢失了一个数字 并且 有一个数字重复 。
给定一个数组 nums 代表了集合 S 发生错误后的结果。
请你找出重复出现的整数,再找到丢失的整数,将它们以数组的形式返回。
示例 1: 输入:nums = [1,2,2,4] 输出:[2,3]
示例 2:输入:nums = [1,1] 输出:[1,2]
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/set-mismatch
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
一、数学解法
时间复杂度O(n)+O(n) = O(2n) = O(n)
首先定义三个变量:
- sum:nums数组所有元素的和
- sumSet:nums数组去重后所有元素的和
- total:1-n的和 可使用等差数列公式计算
重复的数 = sum - sumSet
缺失的数 = total - sumSet
/**
* @param {number[]} nums
* @return {number[]}
*/
var findErrorNums = function(nums) {
let n = nums.length
let sum=0,sumSet=0
let total = (1+n)*n/2
for(let i=0;i<n;i++){
sum += nums[i]
}
const arr = [...new Set(nums)]
for(let j=0;j<arr.length;j++){
sumSet += arr[j]
}
return [sum-sumSet, total - sumSet]
};
二、扫描数组
循环数组解题:时间复杂度O(n)
首先对数据进行升序排序,重复数字为nums[i] == nums[i-1]
丢失的数字有以下三种情况:
- 当nums[0] != 1,丢失的数字是1
- 当nums[-1] != len(nums),丢失的数字是len(nums)
- 那么当nums[i ] - nums[i-1] = 2时, 丢失的数字为nums[i] - 1
var findErrorNums = function(nums) {
let n = nums.length
let lose = 0,repeat =0
nums.sort((a,b)=>a-b)
if(nums[0]!=1){
lose = 1
}
if(nums[n-1]!=n){
lose = n
}
for(let i=1;i<n;i++){
if(nums[i]==nums[i-1]){
repeat = nums[i]
}
if(nums[i]-nums[i-1]==2){
lose = nums[i] -1
}
}
return [repeat,lose]
};
三、哈希表map
时间复杂度和空间复杂度都为O(n)
首先使用1-n的数字建立map,键就是num,值为出现次数
然后出现2次就是重复的,0次就是缺失的
var findErrorNums = function(nums) {
let n = nums.length
let lose = 0,repeat =0
const map = new Map()
nums.forEach(num=>{
map.set(num, (map.get(num) || 0) + 1)
})
for(let i = 1; i <= n; i++){
const count = map.get(i) || 0
if(count == 2) repeat = i
if(count == 0) lose = i
}
return [repeat,lose]
};