题目:645、697
645 错误的集合
理解题意:
数组中包含1~n,缺一个,有一个数字重复。eg:nums=[1,2,2,4],重复的数字为2,缺少的数字为3。要注意数组是无序的
解题思路
①将数组中数字出现的次数存在map中,次数为0即为缺少的数;次数为2,为重复的数。
②学到的一种新思路,使用异或。个人理解,相同的数字异或结果为0,所以把题目数组nums的所有数与原本的1~n异或,相同的为0,剩下的就只有重复的数字和缺少的数字的异或结果,用xor表示。接下来需要考虑的就是怎么把这两个数分开。以2^4为例,结果为110(二进制形式)。用rightmost表示最右边的那个1,即110(加粗部分),此位为1,说明以二进制表示这两个数,他们这位是不相等的。因此可以把nums分成两类:一种是这位为1的xor1,一种是这个位置为0的xor0。要求的两个数分别在这两种之中。怎么从这两类中得到要求的数呢,方法和上面类似,就是把1–n也分成这两类,再次异或,即为所求。只需对nums中是否有此结果进行判断,就可以把重复和缺少的数分开。
需要考虑的是怎样实现提取出xor最右边的1,方法是xor&(-xor),原理是负数用补码表示,是原码的反码加一,考虑原码最右边的那个1,则再往右都为0,反码为1,补码再加1,进位,直到与原码为1位置对应的0变为1,剩下的其余各位均为0。
代码
①
class Solution {
public:
vector<int> findErrorNums(vector<int>& nums) {
int n=nums.size();
vector<int> res(2,0);
vector<int> cnt(n,0);
for(int i=0;i<n;i++)
{
cnt[nums[i]-1]++;
}