题目描述
Given a non-empty 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?
Example 1:
Input: [2,2,1]
Output: 1
Example 2:
Input: [4,1,2,1,2]
Output: 4
找出数组中只出现一次的元素(其余皆出现两次),并返回该元素值。
(时间复杂度要求是线性的,且不开辟额外空间,即时间O(n),空间O(1))
解题思路
看到这题最直接的想法可能是对每个元素进行查找,看是否有重复,但这种方法时间复杂度肯定不是线性的。
一般看到这种时间和空间复杂度的要求,很有可能是巧用位运算了,底层二进制代码运算速度可不是盖的。
这一题是使用异或运算,为什么用这个呢?因为异或运算原理是:
a ^ a = 0
a ^ b =1 (a != b)
0 ^ a = a
异或还满足交换律: a ^ b = b ^ a
所以本题运算过程是:
我们可以想象编译器把 相同的元素都交换到了一起进行异或计算,得到 0
假设数组共有n个元素(根据题意,n为奇数),相同的元素共 (n-1)/2 组,即 共有 (n-1)/2 个0,再不断异或,最终只有1个0
再把这个0和剩下的那个单个数进行异或,得到的就是这个单个数本身了
实现代码
根据上述思路可得Java代码:.
public int singleNumber(int[] nums) {
int res = nums[0]; //res用来存放每次异或的结果,初始值为数组第一个元素
for (int i = 1; i < nums.length; i++) { //所以循环直接从数组第二个元素开始就行
res = res ^ nums[i];
}
return res; //返回的最终异或得结果即为单个数的值
}