1、总结
- 当元素需要标记,又不想创建额外变量的时候,
取反
是一种方法;元素交换/移动
也是一种方法; - 方法四,
通过累加n标记元素
,在原来的逻辑上绕了一点,这种操作需要消化一下;
2、题目
Given an array of integers where 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and others appear once.
Find all the elements of [1, n] inclusive that do not appear in this array.
Could you do it without extra space and in O(n) runtime? You may assume the returned list does not count as extra space.
Example:
Input:
[4,3,2,7,8,2,3,1]
Output:
[5,6]
3、我的方法
方法一:暴力破解:先查找已有的元素,再排除不在的元素
/**
* @param {number[]} nums
* @return {number[]}
*/
// 方法一:
var findDisappearedNumbers = function(nums) {
let tempMap = {};
let resultArr = [];
for(let i = 0; i < nums.length; i++) {
if(nums[i] in tempMap) {
tempMap[nums[i]]++;
} else {
tempMap[nums[i]] = 1;
}
}
console.log(JSON.stringify(tempMap));
for(let j = 1; j < nums.length+1; j++) {
if(!(j in tempMap)) {
resultArr.push(j);
}
}
return resultArr;
};
效率很差了:
4、其他方法
方法二:需要标记数组中的元素,又不想额外的消耗空间,可以将原来的元素取反
/**
* @param {number[]} nums
* @return {number[]}
*/
// 方法二:
var findDisappearedNumbers = function(nums) {
let resultArr = [];
for(let i = 0; i < nums.length; i++) {
let idx = Math.abs(nums[i]) - 1;
if(nums[idx] > 0) {
nums[idx] = -nums[idx];
}
}
//console.log(JSON.stringify(tempMap));
for(let j = 0; j < nums.length; j++) {
if(nums[j] > 0) {
resultArr.push(j+1);
}
}
return resultArr;
};
方法三:将每个元素挪到正确的顺序上,剩下元素不对的元素即为缺失元素
/**
* @param {number[]} nums
* @return {number[]}
*/
// 方法三:
var findDisappearedNumbers = function(nums) {
let resultArr = [];
for(let i = 0; i < nums.length; i++) {
if(nums[i] != nums[nums[i] - 1]) {
let temp = nums[nums[i] - 1];
nums[nums[i] - 1] = nums[i];
nums[i] = temp;
i--;
}
}
//console.log(JSON.stringify(tempMap));
for(let j = 0; j < nums.length; j++) {
if(nums[j] != (j+1)) {
resultArr.push(j+1);
}
}
return resultArr;
};
方法四:这个方法我刚开始没看明白,仔细看其实原理和方法二是一样的,只是方法二通过取反标记正确的元素,这里是通过累加n(累加过后判断小于n的元素,则其没经过累加,对应的索引不在数组中,索引+1得到缺失的元素)
这个方法略有些绕,需要好好消化一下!~
/**
* @param {number[]} nums
* @return {number[]}
*/
// 方法四:
var findDisappearedNumbers = function(nums) {
let resultArr = [];
for(let i = 0; i < nums.length; i++) {
console.log('i:', i);
nums[(nums[i] - 1) % nums.length] += nums.length;
}
console.log(nums);
for(let j = 0; j < nums.length; ++j) {
if(nums[j] <= nums.length) {
resultArr.push(j+1);
}
}
return resultArr;
};