260. 只出现一次的数字 III - 力扣(LeetCode) (leetcode-cn.com)
难度:中等
题目描述:给定一个整数数组 nums,其中恰好有两个元素只出现一次,其余所有元素均出现两次。 找出只出现一次的那两个元素。你可以按 任意顺序 返回答案。
进阶:你的算法应该具有线性时间复杂度。你能否仅使用常数空间复杂度来实现?
分析
1- 这类题可以简单的使用HashMap进行存储,key值为数组元素,value值为元素出现的次数,最后遍历一遍,输出value为1的key即可。
2- 此题进阶为使用异或进行计算,其异或性质在136题有提。
首先使用异或计算数组所有值,最终得到sum值,sum值为两个只出现一次数的异或结果。
在sum值的二进制表示中随便找一位值为1的数,使用此位的数将数组分类。
例如:
nums = [1,1,3,4] ---> [0001,0001,0011,0100]
对数组中进行异或操作获得sum值
sum = 0111,随便取一位值为1的位,这里取最低位,即0001
将nums数组中的每个数的最低位对0001进行异或操作
nums 取最低位为 [0001,0001,0001,0000]
[0001,0001,0001,0000] ^ 0001 = [0000,0000,0000,0001]
可以分为两类,一类为最低位为0的数,一类为最低位为1的数。
分别按照类别将nums中的数值进行异或操作,最终得到的数则为最终结果。
最低位为0 : [0001, 0001, 0011] ---> 0011
最低位为1 : [0100] ---> 0100
方法二解题
class Solution {
public int[] singleNumber(int[] nums) {
int sum = 0;
for (int num :
nums) {
sum ^= num;
}
int k = -1;
for (int i = 0; i < 32; i++) {
if (((sum >> i) & 1) == 1){
k = i;
break;
}
}
int[] result = new int[2];
for (int num :
nums) {
if (((num >> k) & 1) == 1) {
result[1] ^= num;
} else {
result[0] ^= num;
}
}
return result;
}
}