136. 只出现一次的数字
根据左神的数据结构和算法课程整理
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
说明:你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
示例 1: 输入: [2,2,1] 输出: 1 示例 2: 输入: [4,1,2,1,2] 输出: 4
位运算的知识
基本概念:
- 按位与 &:两位全为1,才为1,否则为0
- 按位或 |:两位有一个为1,才为1,否则为0
- 按位异或 ^:两位一个为1,一个为0时的结果为1,否则为0
- 按位取反:0变为1,1变为0
如何计算:
- 正数的原码首位为0,负数首位为1
- 正数的原码、反码、补码都相同(三码合一)
- 负数先算原码,原码首位为1,其余和其正数一样;然后计算其反码,也就是符号位(首位)不变,其他位取反,再算其补码,补码=反码+1
- 结果按照补码计算后再变为源码
按位异或的一些公式:
//一个数与0异或,结果还为这个数
0 ^ a = a;
//一个数与1异或,结果为这个数的反码
1 ^ a = ~a;
//一个数与自己异或,结果为0
a ^ a = 0;
//按位异或满足交换律和结合律
a ^ b ^ c = a ^ (b ^ c);
有了这些知识就可以做这个题了。
解题思路
因为有一些数出现了两次,只有一个数出现了一次,那么把这些数都异或一遍,如果出现过两次,根据交换律,可以先让它们自己进行异或,那么结果为0,最后就只剩下0和出现一次的数进行异或,那么就剩下了这个数。
代码实现
public class SingleNumber {
public static void main(String[] args){
int[] arr = new int[]{1,1,2,2,2,2,3,3,3,3,3,3,4,4,4,4,5,5,5};
System.out.println(SingleNumber.singleNumber(arr));
}
public static int singleNumber(int[] nums) {
int eor = 0;
for (int i = 0; i < nums.length; i++) {
eor = eor ^ nums[i];
}
return eor;
}
}