题目:
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
说明:
你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
示例 1:
输入: [2,2,1]
输出: 1
示例 2:
输入: [4,1,2,1,2]
输出: 4
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/single-number
解法思路:
通过异或运算(两者相等为0,不等为1.)
1^1=0
0^0=0
1^0=1
0^1=1
规律 :
1.交换律:a ^ b ^ c <=> a ^ c ^ b
2.任何数于0异或为任何数 0 ^ n => n
3.相同的数异或为0: n ^ n => 0
如: 2 的二进制为 : 0010
1 的二进制为 : 0001
4 的二进制为 : 0100
实例1中:逐步预算
2^2 = 0000 = 0
1^0 = 0001 = 1
等价为 : 2^2^1 = 0^1 = 1
实例2中:逐步运算
4^1 => 0100 ^ 0001 => 0101 = 5
5^2 => 0101 ^ 0010 => 0111 = 7
7^1 => 0111 ^ 0001 => 0110 = 6
6^2 => 0110 ^ 0010 => 0100 = 4
等价为 : 4^1^2^1^2 => 4^1^1^2^2 => 4^(1^1)^(2^2) => 4^0^0 = 4(相同的数异或为0: n ^ n => 0)
衍生出的面试题:
int a = 10,b=20;交换两个数的值:
常规写法:
int temp = 0;
temp = a;
a = b;
b = temp;
那么不定义第三方变量,交换两个数的值:
a=a+b;
b=a-b;
a=a-b; //可能会存在a+b的值超过类型的大小,所以要谨慎。
接下来的就是使用异或:
a=a^b;
b=a^b;
a=a^b;
逐步运算
a = a ^ b;
b = a ^ b = (a ^ b) ^ b = a ;
a = a ^ b = (a ^ b) ^ (a ^ b) ^ b = b;