每日进步
- 求绝对值:
Math.abs()
题目
给定一个数组,包含从 1 到 N 所有的整数,但其中缺了两个数字。你能在 O(N) 时间内只用 O(1) 的空间找到它们吗?
以任意顺序返回这两个数字均可。
- 示例 1:
- 输入:[1]
- 输出:[2,3]
- 示例 2:
- 输入:[2,3]
- 输出:[1,4]
- 提示:
- nums.length <= 30000
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/missing-two-lcci
著作权归领扣网络所有。本文仅供个人学习,非商用。
题解
从限制条件入手的解法:
我利用数组的位下标i
和对应值nums[i]
的正负来记录数组nums
中是否包含整数i+1
。
- 我们可以用N位的数组来记录N个数据是否出现。由于
nums
数组缺少两个值,长度为N-2,因此我们需要创建一个长度为2的数组last2
来记录最后两个元素是否出现。- 我们使用
nums[0: n-3]
和last2[0: 1]
来记录N个数据是否出现,若出现则将值修改为相反数。由于原始值全部大于0,所以当最终第tmp
位小于0时,表面数组nums
中包含整数tmp+1
- 我们使用
- 记录存在信息,遍历
nums
数组:- 首先,我们提取
nums
数组包含的原始数据。由于后面会将部分值修改为相反数,因此计算数组值的绝对值:tmp = Math.abs(nums[i])
。 - 然后,将
nums[tmp-1]
或者last2[tmp-nums.length-1]
修改为原来的相反数,这样既不损失数组中原本包含的信息,又记录了数组是否包括整数tmp
。
- 首先,我们提取
- 检索存信息,遍历
nums
数组和last2
数组:- 若位置
i
上的值nums[i]
小于0,说明nums
数组中包含整数i+1
- 若位置
i
上的值nums[i]
大于0,说明nums
数组中缺少整数i+1
,这样就找到了其中一个答案
- 若位置
优点: 相比于网上的其他题解,本方法可以更轻松地扩展到缺少m个数据的情况。即,将长度为2的数组last2
替换为长度为m的数组lastm
。
代码:
class Solution {
public int[] missingTwo(int[] nums) {
int[] last2 = {
1, 1};
int[] ans = {
0, 0};
for (int i = 0; i < nums.length; i++){
int tmp = Math.abs(nums[i]);
if (tmp <= nums.length){
nums[tmp-1] = -nums[tmp-1];
}else{
last2[tmp-nums.length-1] = -1;
}
}
for (int i = 0; i < nums.length; i++){
if (nums[i] > 0){
if (ans[0] == 0)
ans[0] = i+1;
else
ans[1] = i+1;
}
}
for (int i = 0; i < last2.length; i++){
if (last2[i] > 0){
if (ans[0] == 0)
ans[0] = i+1+nums.length;
else
ans[1] = i+1+nums.length;
}
}
return ans;
}
}
执行用时和内存消耗如下所示: