本文最后更新于 1394 天前,其中的信息可能已经有所发展或是发生改变。
前置知识:yvanwzw.top/index.php/2021/03/17/一些特殊的位运算/
原题1:
来源:https://leetcode-cn.com/problems/shu-zu-zhong-shu-zi-chu-xian-de-ci-shu-lcof/
一个整型数组 nums 里除两个数字之外,其他数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。
示例 1:
输入:nums = [4,1,4,6]
输出:[1,6] 或 [6,1]
示例 2:
输入:nums = [1,2,10,4,1,4,3,3]
输出:[2,10] 或 [10,2]
题目的难点在于对时间复杂度和空间复杂度的要求,故而不能用HASH之类的方法
根据异或的特性,a^b^a=b ,从而得到a^a^b^b^……^y^y^z=z
因为有两个解,所以为了解这道题,还需要利用分组的方法(见前置知识)
首先,其余有相同的解的值都被相互抵消,故而全部异或后相当于两个解的异或值x
再令temp=x&(-x),从而得到两个解的二进制数中最后一位不同(右为后)的数(即只有最后不同的一位为1,其余为0)
利用(temp&num)==1或(temp&num)==temp从而使所有的数根据那一位分成了两组,即那一位为0的组和为1的组
这两组分别包含了其中一个解,于是两组分别进行异或,最终得到所求答案
代码如下:
vector<int> singleNumbers(vector<int>& nums) {
int x=0;
vector<int> ans={0,0};
for(auto num:nums)
x^=num;
int temp = x&(-x);
for(auto num:nums)
if((num&temp)==0)
ans[0]^=num;
else
ans[1]^=num;
return ans;
}