版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/YYZZHC999/article/details/88379976
题目:
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。要求尽量不使用额外空间
示例 1:
输入: [2,2,1]
输出: 1
示例 2:
输入: [4,1,2,1,2]
输出: 4
/**
* 只出现一次的数字
* @author 天赋吉运-杨晓慧
* @create 2019-03-09 21:28
*/
public class singleNumber {
public static void main(String[] args) {
int[] nums= {1,1,2,4,2};
int i = singleNumber(nums);
System.out.println(i); // 输出的结果是4
}
/**
* 只出现一次的数字
* @param nums 传入数组
* @return 只出现一次的数字
*/
public static int singleNumber(int[] nums) {
int x=0;
for(int i=0;i<nums.length;i++){
// 按位异或操作
x=x^nums[i];
}
return x;
}
}
一开始没有任何思路,后来看网友的评论说用java的异或操作可以完美解决这个问题,这才想到把java逻辑运算符练了一把。
/**
*java 里的逻辑运算符,与(&)或(|)和异或(^)
*/
public static void test() {
int x = 5;
int y = 11;
System.out.println(x|y); // |是按位或--- 输出15
System.out.println(x&y); // &是按位与---输出1
System.out.println(x^y); // ^是按位异或--- 输出14
}
过程是这个样子:
x=5 (0101二进制)
y=11(1011二进制)
x|y = 1111 = 15
x&y = 0001 = 1
x^y = 1110 =14
解决这道题主要是用到了异或运算符。
java中异或(用符号XOR或者 ^ 表示)操作的性质了解一下:
1、交换律 a ^ b = b ^a
2、结合律(即(a ^ b) ^ c == a ^ (b ^ c))
3. 任意x,都有x ^ x=0,x ^0=x
4、自反性 A XOR B XOR B = A xor 0 = A
本题的中心思想是这样的:
- 一个数和自己异或为0
- 任何一个数和0异或都取本身
- 所以,一个数和同一个数异或两次之后还是自己. (偶数次都可以,所以本题的题目里备注了是出现两次)
如果重复出现的是奇数次,比如三次或五次,最后的结果一定是所有出现奇数次的数字一起取异或。
举个小例子验证一下这些性质:
4^1 异或 :
0100 (4)
0010 (1)
结果: 0110 (5)
再次与1异或,相当于4^ 1 ^1:
0110 (5)
0010 (1)
结果:0100 (4)
所以一个数与另外一个数异或偶数次之后还等于自己本身,
也换这个角度想: 4^ 1 ^ 1=4 ^ (1 ^ 1)=4^0=4
本题中数组中的4与另外两个数都异或了两次,所以最后异或结果还是4.
以上代码笔者已经过验证,读者阅后可以自行亲测,欢迎交流, 一起写高质量的代码。