错误的集合
集合 s 包含从 1 到 n 的整数。不幸的是,因为数据错误,导致集合里面某一个数字复制了成了集合里面的另外一个数字的值,导致集合 丢失了一个数字 并且 有一个数字重复 。
给定一个数组 nums 代表了集合 S 发生错误后的结果。
请你找出重复出现的整数,再找到丢失的整数,将它们以数组的形式返回。
示例 1:
输入:nums = [1,2,2,4]
输出:[2,3]
示例 2:
输入:nums = [1,1]
输出:[1,2]
提示:
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/set-mismatch
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路1:哈希表
这个没啥好说的。
code
class Solution {
public:
vector<int> findErrorNums(vector<int>& nums) {
int n = nums.size();
vector<int> cnt(n + 1,0);
for(auto item : nums) cnt[item] ++;
vector<int> ans(2,0);
for(int i = 1;i <= n;i ++)
{
if(cnt[i] == 0) ans[1] = i;
if(cnt[i] == 2) ans[0] = i;
}
return ans;
}
};
位运算
为了在常数空间内实现,需要使用位运算,实际上像是这种出现偶数次的通常可以考虑使用异或消除,但是本文中出现偶数次的是重复的数字,也是最后的结果,我们并不希望消除掉,怎么办呢?
- 在数组中添加1-n,这样重复的数字和缺失的数字都是奇数次,其余数字都是偶数次
- 全部异或就可以将其余数字全部去除
- 记x为重复的数字,y为缺失的数字,最后的结果为x ^ y
- 如何在2n个数字中找到x和y呢
- lowbit(x ^ y)为x和y的最低不同位,根据最低不同位区分x和y,将2n个数字都分到两个不同的组别中,同时每个组中可以通过异或消除重复的数字,找到x和y
- 最后判别x和y哪个是重复的哪个是缺失的
code
class Solution {
public:
int lowbit(int x)
{
return x & (-x);
}
vector<int> findErrorNums(vector<int>& nums) {
int n = nums.size();
int xy = 0;
for(auto item : nums) xy = xy ^ item;
for(int i = 1;i <= n;i ++) xy = xy ^ i;
int diff = lowbit(xy);
int nums1 = 0,nums2 = 0;
for(auto item : nums)
{
if((item & diff) == 0) nums1 ^= item;
else nums2 ^= item;
}
for(int i = 1;i <= n;i ++)
{
if((i & diff) == 0) nums1 ^= i;
else nums2 ^= i;
}
for(auto item : nums)
{
if(item == nums1) return {nums1,nums2};
}
return {nums2,nums1};
}
};
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理