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,详细原因大部分老师应该都提过,就不赘述了。