645. 错误的集合
一、题目
集合 S 包含从1到n的整数。不幸的是,因为数据错误,导致集合里面某一个元素复制了成了集合里面的另外一个元素的值,导致集合丢失了一个整数并且有一个元素重复。
给定一个数组 nums 代表了集合 S 发生错误后的结果。你的任务是首先寻找到重复出现的整数,再找到丢失的整数,将它们以数组的形式返回。
示例 1:
输入: nums = [1,2,2,4]
输出: [2,3]
注意:
- 给定数组的长度范围是 [2, 10000]。
- 给定的数组是无序的。
二、题解
法1
- 嵌套for遍历找到错误值
- 由于发生错误前后只有,数组只有正确值变成了错误值,其余的数不变,因此其余数的总和发生错误前后也相等
- 正确总和 - 正确值 = 错误总和 - 错误值
- 正确值 = 正确总和 - (错误总和 - 错误值)
- 由于是从1开始连续的数,用等差数列求和——(最小值+最大值)*个数 / 2
- 由于是从1开始连续的数,最小值为1
- 由于是从1开始连续的无序数组,数组多长,最大值就应该有多大
class Solution {
public int[] findErrorNums(int[] nums) {
int wrongNum = 0;
int rightNum = 0;
int rightSum = 0;
int wrongSum = 0;
for (int i = 0; i < nums.length; i++) {
for (int j = i+1; j < nums.length; j++) {
if (nums[i]==nums[j]) {
wrongNum = nums[i];
}
}
wrongSum+=nums[i];
}
rightSum = (1 + nums.length) * nums.length/ 2;
rightNum = rightSum - (wrongSum - wrongNum);
return new int[]{wrongNum,rightNum};
}
}
-
时间复杂度O(n^2)
-
空间复杂度O(1),使用恒定的额外空间。
-
执行用时:715 ms, 在所有 Java 提交中击败了5.62%的用户
-
内存消耗:39.9 MB, 在所有 Java 提交中击败了90.52%的用户
法2
- 创建一个存储数组,用于统计出现两次的数——错误值
- 由于给定数组是从1开始的连续数组
- 所以给定数组中每一个元素都可以作为存储数组的索引
- 所以存储数组从1开始存数,存给定数组的n个数,所以存储数组长度应为n+1
- 存储数组初始为0
- 因此当同一个索引存入了相同的一个数,存储数组值+1,则那个数就是错误值
- 由于正确值的缺失,因此以正确值为索引的那一个元素,不会存入数,仍然为初始值0
- 再从索引1遍历一遍存储数组,值为0的那个数的索引就是正确值
class Solution {
public int[] findErrorNums(int[] nums) {
int rightNum = 0;
int wrongNum = 0;
int[] cnt = new int[nums.length+1];
for (int i = 0; i < nums.length; i++) {
if (cnt[nums[i]]!=0) {
wrongNum = nums[i];
}
cnt[nums[i]]++;
}
for (int i = 1; i < cnt.length; i++) {
if (cnt[i]==0) {
rightNum = i;
}
}
return new int[]{wrongNum,rightNum};
}
}
- 时间复杂度O(n)
- 空间复杂度O(n)。
- 执行用时:1 ms, 在所有 Java 提交中击败了100.00%的用户
- 内存消耗:40.3 MB, 在所有 Java 提交中击败了53.50%的用户
法3
-
- 不使用额外空间,使用nums本身作为存储空间
- 正数为出现次数为0的数,负数表示出现次数大于等于1的数
-
例子[2, 3, 2]
-
统计的数字 1 2 3 nums的索引 0 1 2 nums的元素 2 3 2 第一轮 -3 第二轮 -2 第三轮 N<0 记录|-2| nums最终结果 2 -3 -2 - 错误的数为记录的值
- 正确的数为正数的索引+1——1
class Solution {
public int[] findErrorNums(int[] nums) {
int corNum = 0;
int wroNum = 0;
for (int i = 0; i < nums.length; i++) {
if (nums[Math.abs(nums[i])-1]>0) {
nums[Math.abs(nums[i])-1] *= -1;
} else {
wroNum = Math.abs(nums[i]);
}
}
for (int i = 0; i < nums.length; i++) {
if (nums[i]>0) {
corNum = i+1;
}
}
return new int[]{wroNum,corNum};
}
}
-
时间复杂度O(n)
-
空间复杂度O(1)
-
执行用时:3 ms, 在所有 Java 提交中击败了72.30%的用户
-
内存消耗:39.6 MB, 在所有 Java 提交中击败了97.73%的用户

浙公网安备 33010602011771号