avatar

目录
136只出现一次的数字

题目链接

题目描述:

给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。

说明:

你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?

示例 :

输入: [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]就是唯一一个只有一个的数组元素,即为结果。

哈希表

cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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";
}
};

位运算

cpp
1
2
3
4
5
6
7
8
9
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;
}
};

如果有错误或者不严谨的地方,请务必给予指正,十分感谢。

文章作者: breadhunter
文章链接: http://yoursite.com/2020/03/14/136%E5%8F%AA%E5%87%BA%E7%8E%B0%E4%B8%80%E6%AC%A1%E7%9A%84%E6%95%B0%E5%AD%97/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 breadhunter
打赏
  • 微信
    微信
  • 支付寶
    支付寶