136. 只出现一次的数字
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
思路:本来使用HashMap做,后来才知道这是位运算方面的题,惭愧。
由于其他元素都出现了两次,因此把全部元素亦或一下,结果就出来了。。
class Solution { public static int singleNumber(int[] nums) { int result=0; for(int i=0;i<nums.length;i++){ result^=nums[i]; } return result; } }
137. 只出现一次的数字 II
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现了三次。找出那个只出现了一次的元素。
思路:其他元素都出现了三次,按位计算每一位上1的个数,结果模3为1的那些位就是所求数二进制1所在的位。
class Solution { public static int singleNumber(int[] nums) { int result = 0; for(int i=0;i<32;i++){ int mask = 1<<i; int count = 0; for(int j=0;j<nums.length;j++){ if((mask&nums[j])!=0) count++; } if(count%3==1) result = mask|result; } return result; } }
260. 只出现一次的数字 III
给定一个整数数组 nums
,其中恰好有两个元素只出现一次,其余所有元素均出现两次。 找出只出现一次的那两个元素。
思路:
原话:
这道题主要和Ⅰ类似,但是这里有两个不同的数,所以需要从这两个数的异或值反推得到结果。整数的二进制在java中是补码表示,所以我们可以用n&-n得到n的二进制最右边的一个1。这样对于这个为1的位置,肯定可以分辨出这两个数,因为一定有两个数在这个位置1个为1,另一个为0。所以遍历整个数组,和这个数做&操作,就可以将两个数分开到两组中。因为其他出现两次的数,异或操作还是为0,对结果没有影响,所以对每个遍历到的数做异或操作即可。
理解:
还是先将全部数亦或一下,得到的结果n就是我们要的两个数亦或的结果。然后反推这两个数。n&-n(不好理解的话可以换为n & ~(n-1)理解)得到两个数不同的最低位。接着将全部数分成两个组,一组为该位上是0的,另一组为该位上是1的。把两组分别组内亦或,就可以得到我们要的两个数。
class Solution { public int[] singleNumber(int[] nums) { int sum = 0; //记录所有异或的值,即两个只出现一次数的异或 for(int i=0;i<nums.length;i++){ sum ^= nums[i]; } int[] res = new int[2]; sum &= -sum; //得出两个数异或结果的最右边的一个1,其他的为零,这样进行&操作就可以将两个不同的数分到不同的两组去 for(int i=0;i<nums.length;i++){ if((sum&nums[i])==0) res[0] ^= nums[i]; else res[1]^=nums[i]; } return res; } }https://www.cnblogs.com/271934Liao/p/7158888.html