Single NumberIII(leetcode260)
题目
- 给定一个数组nums,有两个元素只出现了一次,其余的元素都出现了两次,找出只出现了一次的两个元素
- 举例:输入[1,2,1,3,2,5],输出[3,5]
- 采用位运算进行
解题思路
- 首先根据异或性质,两个相同的数异或为0,0和任意数异或结果为任意数,数组中只有两个数出现1次,其余出现一次
- 根据以上性质,我们可以将数组所有值异或得到这两个数的异或结果temp = one ^ two
- 此时需要将这两个数分开,此时可以反向考虑,我们异或得到的结果肯定不为0那么这个temp的二进制表示某一位上必然有1的存在
- 我们可以根据某一位上1的存在根据这一位将原始数组分为两组,一组这一位上包含这个1,另一组这一位上不包含这个1,如果one和two这两个数在这一位都是1的话,根据异或性质这一位就是0,所以必然可以根据1这位将数组分为两部分
- 分组之后的数据再进行数组异或最后就可以得到one和two,因为分组之后一组之中只有一个数据出现1次,其余的数据全部出现两次,根据异或结果最后就是这个出现1次的数据
- 举例来说:示例中temp = 3 ^5 = 6,二进制表示是110,此时第二位表示为1,那么我们可以用010这个数据去和数据进行与操作,结果不为0的是一组结果为0的是另一组就可以将3和5分别划分到两组中,然后组内数据相与就可以找到对应的数字
源代码实现
class Solution {
public int[] singleNumber(int[] nums) {
int[] result = new int[2];
int temp = 0;
//假设这两个数变量分别是one和two,根据异或性质temp = one^two;
for (int i = 0; i < nums.length; i++) temp ^= nums[i];
int count = 0;
//找到第一个不为0的位,count用于计数还原
while ((temp & 1) == 0) {
temp >>= 1;
count++;
}
temp = 1;
//此时根据count将这个数据还原,示例中还原为010形式,移位实现
while (count != 0) {
temp <<= 1;
count--;
}
//根据temp进行分类实现结果
for (int i = 0; i < nums.length; i++) {
if ((temp & nums[i]) == 0) result[0] ^= nums[i];
else result[1] ^= nums[i];
}
return result;
}
}
本文标题:Single NumberIII(leetcode260)
本文链接:https://www.haomeiwen.com/subject/zmvjqqtx.html
网友评论