您的位置:首页 > 其它

异或(XOR)在算法中的一些适用情况

2015-07-10 15:46 197 查看
今天在做leetcode上的一道题时,发现了一种对异或操作的使用情况。

题目是这样子的:

Given an array of integers, every element appears twice except for one. Find that single one.

给你一个整型的数组,除了一个元素之外其余元素都只出现了两次,找到那一个独立的元素

Note:
Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?

算法要求时间复杂度是线性的,并且问你能否改进成不需要多余的内存。

这个题目本身如果没有算法要求是很简单的,如下:

int singleNumber(vector<int>& nums) {
for(vector<int>::iterator iter = nums.begin(); iter != nums.end(); ++iter){
vector<int>::iterator pos = find(iter+1, nums.end(), *iter);
if(pos != nums.end())
nums.erase(pos);
}
return nums[0];
}


但是for循环遍历需要o(N)的复杂度,而find()也需要最少o(N)的复杂度,所以不满足题目对时间复杂度的要求。

这个时候百思不得其解,看看别人的答案,用到了 ^= ,思考了一下有不明白其中的原理,之前看CSAPP的时候学过XOR的操作,但是不明白为什么要用到这里。最后又搜了一下这个题目,终于明白其中的原委。

因为其他元素都出现了2次,因此根据XOR满足交换律的要求,可以知道其他所有元素(不包括那个只出现一次的元素)异或的结果是各个bit均为0的int,而一个变量各位均为0的话和其他变量进行XOR操作结果就是那个元素,这样就可以求出结果了。代码如下:

int singleNumber(vector<int>& nums) {
int result = 0;
if(nums.size() == 1) return nums[0];
for(vector<int>::iterator iter = nums.begin(); iter != nums.end(); ++iter){
result ^= *iter;
}
return result;
}


这个题目有一个升级版,就是在数组中有两个只出现一次的元素,让你求出,这里只给出一个思路:将数组拆分成两个子数组,每个数组都只包含一个所要求的元素。具体解法在这里。我就不当搬运工了。

这种题目的特点就是 其他元素一定要出现偶数次。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: