LeetCode - 136. Single Number - ( C++ ) - 解题报告 - 位运算思路 xor

时间:2022-10-01 16:41:10

1.题目大意

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?

给定一个数组的整数,数组中的每个元素都出现了两次。例外地,有一个元素只出现了一次。找出那个只出现了一次的元素。

要求:算法的时间复杂度应是线性的,不需要额外的存储空间。

2.思路

纵观全题,我的第一想法是先排序,然后开始一加一减,最后取绝对值。当然,第一想法都比较幼稚。互相握手的想法就更加不现实了。

第二想法是,先排序,然后相邻元素对比,例如这样的思路:

class Solution {
public:
int singleNumber(vector<int>& nums) {
sort(nums.begin(),nums.end());
for(int i=0;i<nums.size();i+=2)
if(nums[i]!=nums[i+1])
return nums[i];
return 0;
}
};

当然,这个思路是可以AC的,但是要考虑到sort()的时间复杂性在C++里面是$O(nlogn)$。虽然在之后的筛查中复杂度是$O(n)$,但在sort()这一步,显然不算线性了。LeetCode似乎很多时候判的比较松。

这题刚好我是跟另一题一起看的,看完题我就出去吃饭了,另一题刚好用到位运算,…… 呃好像要扯远了,反正另一种方法就是位运算中的xor。稍微解释一下的话,就是相同位不同则为1,相同位相同则为0。符号是 ^

比如 11101 ^  10110 = 01011

在11101和10110中:

第一位都是1,相同位相同,因此结果的第一位为0;

第二位分别是1和0,相同位不同,因此结果的第二位为1。

以此类推。

用这种方法实现的代码是:

class Solution {
public:
int singleNumber(vector<int>& nums) {
int result=0;
for (int i=0;i<nums.size();i++)
result= result ^ nums[i];
return result;
}
};

  

3.应当注意的地方

这题主要要注意的地方还是出现在第一种实现方法里的。

首先是vector的特性,要用sort()的时候的用法跟一般数组使用的时候不大一样(具体参见代码)。

第二点是如果漏了最后一行

return 0;

就会提示warning: control reaches end of non-void function,详细原因大部分老师应该都提过,就不赘述了。