题目链接
题目描述:
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
说明:
你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
示例 :
输入: [2,2,1]
输出: 1
解题思路
两种思路,第一种非常简单,利用哈希表记录数组元素出现频次即可。空间复杂度O(n),如果想将其降至O(1)呢?
理解题设,除了某个元素只出现一次以外,其余每个元素均出现两次,这时想到一种位运算——异或。
关于异或:
- 如果a、b两个值不相同,则异或结果为1。如果a、b两个值相同,异或结果为0(假设a,b只能取0 / 1)
- a xor a = 0
- b xor 0 = b
- 异或运算满足交换律:a xor b xor a = (a xor a) xor b = b xor 0 = b
所以,我们可以通过对数组进行累加的异或运算,得到最终结果。因为,result = nums[0] ^ nums[1] ^ nums[2] ^ nums[3] ^ ...,异或满足交换律使得相同的两元素先一起进行运算得到0,那么根据题设可知最后会剩下0 ^ nums[i],那个nums[i]就是唯一一个只有一个的数组元素,即为结果。
哈希表
class Solution {public:int singleNumber(vector<int>& nums) {unordered_map<int,int> record;for(int i = 0; i < nums.size(); i++){record[nums[i]]++;}for(auto iter = record.begin(); iter != record.end(); iter++){if(iter->second == 1){return iter->first;}}throw "wrong input";}};
位运算
class Solution {public:int singleNumber(vector<int>& nums) {int result = nums[0];for(int i = 1; i < nums.size(); i++)result = result ^ nums[i];return result;}};
如果有错误或者不严谨的地方,请务必给予指正,十分感谢。
