>[success] # 找到所有数组中消失的数字
* 题目描述
给你一个含 n 个整数的数组 nums ,其中 nums[i] 在区间 [1, n] 内。请你找出所有在 [1, n] 范围内但没有出现在 nums 中的数字,并以数组的形式返回结果。
* 示例 1:
输入:nums = [4,3,2,7,8,2,3,1]
输出:[5,6]
* 示例 2:
输入:nums = [1,1]
输出:[2]
* 提示:
n == nums.length
1 <= n <= 105
1 <= nums[i] <= n
进阶:你能在不使用额外空间且时间复杂度为 O(n) 的情况下解决这个问题吗? 你可以假定返回的数组不算在额外空间内。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/find-all-numbers-disappeared-in-an-array
>[danger] ##### 第一次解题思路
题目中规则是长度为`n` 且数组中值只包含在`[1,n]`,因此可以使用原地修改数组方法,将出现值所映射的脚标对应的值取反即可,如果该值已经为负数说明出现过一次则不取反,最后只要统计所有为正数的index 即为没出现的值
* js 代码
~~~
var findDisappearedNumbers = function(nums) {
// 将数组值所映射对应角标的值 取反
nums.forEach((cur) => {
const index = Math.abs(cur) - 1
if (nums[index] > 0) {
nums[index] *= -1
}
return cur
})
// 如果是正数说明该值没出现过
return nums.reduce((acc, cur, index) => {
if (cur > 0) acc.push(index + 1)
return acc
}, [])
};
~~~
![](https://img.kancloud.cn/21/06/21067128a4735af969e0552e2b8283ae_1025x694.png)
![](https://img.kancloud.cn/25/b9/25b9de1d5915f5559397a723752abad0_1082x440.png)
>[info] ## 题解
* 使用 **加n** 方法
1. 获取当前值,以该值作为脚标获取对应数组映射值
2. 将映射值进行 **+n** 其中n 为当前**数组长度**
![](https://img.kancloud.cn/0b/a4/0ba4d37f672020e2639631047bd5882f_1007x568.png)
注:在不停加n 过程中想获取对应的映射值不能在单纯的只是以当前值做数组下标,而是要通过取余形式即 **(num-1) % n**,有个小知识点 **(值)取余(取余值) 值 < 取余值** 取余结果为**值** 例如`6%8 = 6`
>[danger] ##### js
~~~
/**
* @param {number[]} nums
* @return {number[]}
*/
var findDisappearedNumbers = function(nums) {
// 将对应值映射作为脚标所映射值加数组长度
const {length} = nums
nums.forEach(num => {
// 获取当前值映射key
const idx = (num-1) % length
nums[idx] += length
})
return nums.reduce((acc, cur, index) => {
// 小于当前数组长度的都是符合的
if(cur <= length){
acc.push( index + 1 )
}
return acc
},[])
};
~~~
>[danger] ##### java
~~~
import java.util.List;
import java.util.ArrayList;
public class Solution {
public List<Integer> findDisappearedNumbers(int[] nums) {
int len = nums.length;
List<Integer> ls = new ArrayList();
for(int i=0; i< len; i++){
// 获取 当前值映射的对应index
int idx = (nums[i] - 1)%len;
nums[idx] += len;
}
// 找到所有小于 length 值
for(int i=0;i< len; i++){
if(nums[i] <= len) ls.add(i+1);
}
return ls;
}
}
~~~
>[danger] ##### 其他
* 先去重在依次去找
~~~
var findDisappearedNumbers = function(nums) {
const set = new Set(nums)
const {length} = nums
const ls = []
for(let i =length;i>0;i--){
if(!nums.includes(i)) ls.push(i)
}
return ls
};
~~~
>[success] # 总结
思路就是使用 数组值绝对和数组长度进行匹配,然后将当前项作为index 去改变映射项,最后找到没有按照规则改变的值,即为不存在值
- 刷题准备
- 统计数组中元素出现次数
- Leetcode -- 442数组中重复的数据
- leetcode -- 448 找到所有数组中消失的数字
- 字符类似题
- Leetcode -- 1002 查找共用字符
- Leetcode -- 1370上升下降字符串
- 指针类题解
- Leetcode -- 283 移动零
- Leetcode -- 26. 删除有序数组中的重复项
- Leetcode -- 80. 删除有序数组中的重复项 II
- Leetcode -- 27. 移除元素
- Leetcode -- 344. 反转字符串
- Leetcode -- 125 验证回文串
- Leetcode -- 11 盛最多水的容器
- Leetcode -- 1480. 一维数组的动态和