错误的集合_leetcode
Posted 勇敢牛牛不怕困难@帅
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了错误的集合_leetcode相关的知识,希望对你有一定的参考价值。
力扣第645.题------错误的集合
题目:
集合 s 包含从 1 到 n 的整数。不幸的是,因为数据错误,导致集合里面某一个数字复制了成了集合里面的另外一个数字的值,导致集合 丢失了一个数字 并且 有一个数字重复 。
给定一个数组 nums 代表了集合 S 发生错误后的结果。
请你找出重复出现的整数,再找到丢失的整数,将它们以数组的形式返回。
分析:
根据题目的意思1到n的数字,原本应该是连续且单一的,然而在复制的过程种出现了复制出错的情况,题目的意思就是要我们找出重复出现的整数和原本的数字。将数组排序之后,比较每对相邻的元素,即可找到错误的集合。寻找重复的数字较为简单,如果相邻的两个元素相等,则该元素为重复的数字。寻找丢失的数字相对复杂,可能有以下两种情况:
- 如果丢失的数字大于 1且小于 n,则一定存在相邻的两个元素的差等于 2,这两个元素之间的值即为丢失的数字;
- 如果丢失的数字是 1或 n,则需要另外判断。
为了寻找丢失的数字,需要在遍历已排序数组的同时记录上一个元素,然后计算当前元素与上一个元素的差。考虑到丢失的数字可能是 11,因此需要将上一个元素初始化
所以最后的思路就是小于n值我们根据两数之差来判断丢失的数字,而n最后一个数字需要另做判断。
代码:
public int[] findErrorNums(int[] nums) {
int[] errorNums = new int[2];//声明一个数组,作为返回对象
int n = nums.length;//nums的长度
Arrays.sort(nums);//对nums进行排序
int prev = 0;//记录重复元素
for (int i = 0; i < n; i++) {
int curr = nums[i];
if (curr == prev) {
errorNums[0] = prev;
} else if (curr - prev > 1) {
errorNums[1] = prev + 1;
}
prev = curr;
}
if (nums[n - 1] != n) {
errorNums[1] = n;
}
return errorNums;
}
public static void main(String[] args) {
int n[] = {1,2,4,2,5,6};
int m[] = findErrorNums(n);
System.out.println(m[0]+" "+m[1]);
}
结果:
第二种解题方式hash表:
重复的数字在数组中出现 2 次,丢失的数字在数组中出现 0 次,其余的每个数字在数组中出现 1 次。因此可以使用哈希表记录每个元素在数组中出现的次数,然后遍历从 1 到 n 的每个数字,分别找到出现 2 次和出现 0 次的数字,即为重复的数字和丢失的数字。
代码:
class Solution {
public int[] findErrorNums(int[] nums) {
int[] errorNums = new int[2];
int n = nums.length;
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
for (int num : nums) {
map.put(num, map.getOrDefault(num, 0) + 1);
}
for (int i = 1; i <= n; i++) {
int count = map.getOrDefault(i, 0);
if (count == 2) {
errorNums[0] = i;
} else if (count == 0) {
errorNums[1] = i;
}
}
return errorNums;
}
}
第三种解题方法
重复的数字在数组中出现 22 次,丢失的数字在数组中出现 00 次,其余的每个数字在数组中出现 11 次。由此可见,重复的数字和丢失的数字的出现次数的奇偶性相同,且和其余的每个数字的出现次数的奇偶性不同。如果在数组的 nn 个数字后面再添加从 11 到 nn 的每个数字,得到 2n2n 个数字,则在 2n2n 个数字中,重复的数字出现 33 次,丢失的数字出现 11 次,其余的每个数字出现 22 次。根据出现次数的奇偶性,可以使用异或运算求解。
class Solution {
public int[] findErrorNums(int[] nums) {
int n = nums.length;
int xor = 0;
for (int num : nums) {
xor ^= num;
}
for (int i = 1; i <= n; i++) {
xor ^= i;
}
int lowbit = xor & (-xor);
int num1 = 0, num2 = 0;
for (int num : nums) {
if ((num & lowbit) == 0) {
num1 ^= num;
} else {
num2 ^= num;
}
}
for (int i = 1; i <= n; i++) {
if ((i & lowbit) == 0) {
num1 ^= i;
} else {
num2 ^= i;
}
}
for (int num : nums) {
if (num == num1) {
return new int[]{num1, num2};
}
}
return new int[]{num2, num1};
}
}
以上是关于错误的集合_leetcode的主要内容,如果未能解决你的问题,请参考以下文章
leetcode_1292. Maximum Side Length of a Square with Sum Less than or Equal to Threshold_[二维前缀和](代码片段
LeetCode题目记录-645. 错误的集合(C++代码实现)