HOT100题打卡第28天——位运算
哈喽各位,今天终于开了一个新篇——技巧篇
来看看今天的题目
136. 只出现一次的数字
给你一个 非空 整数数组 nums ,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
你必须设计并实现线性时间复杂度的算法来解决此问题,且该算法只使用常量额外空间。
示例 1 :
输入:nums = [2,2,1]
输出:1
分析题目
首先拿到这个题目我就想到用哈希表来做,建一个布尔类型的map集合,然后遍历数组,如果是第一次遇到这个数,就把这个数作为键存入表中,对应的值是true,因为目前不重复,后续如果再次遇到这个数,重复了,那么这时就可以利用键的唯一性,把当前数再次存入map中,值为false,覆盖上一次的数据,最后遍历hash表找出值为true的键就可以了
然后得到的代码如下:
代码
class Solution {public int singleNumber(int[] nums) {//用一个哈希表来储存元素和重复结果,如果当前元素重复,则value是trueMap<Integer, Boolean> hm = new HashMap<>();//遍历数组,判断当前元素是否在hash表中存在for (int num : nums) {boolean value = hm.containsKey(num);//如果当前map中不包含当前数,那么返回值value是false,表示没有这个数//存进表中,false表示没有重复//如果后面数组又遍历到相同数,此时contains方法返回值就是true,再次存入map,true表示重复hm.put(num, value);}for (Map.Entry<Integer, Boolean> entry : hm.entrySet()) {//最后挑出不重复的一个if (!entry.getValue()) {return entry.getKey();}}return -1;}
}
提交了能通过,但是并不满足常量空间条件
看了一下标签,可以用位运算来帮助解决这道题,这题用到的是异或的特性
异或的三大特性:
异或运算用符号 ^ 表示,对两个二进制位进行操作,规则是:
1.相同为 0,不同为 1
2.任何数与 0 异或,结果仍是该数(a ^ 0 = a)。
3.任何数与自身异或,结果为 0
代码如下
class Solution {public int singleNumber(int[] nums) {int n=nums.length;int res=0;for(int i=0;i<n;i++){res^=nums[i];} return res;}
}
所有出现 2 次的元素,通过 “x ^ x = 0” 相互抵消,对最终结果无影响;
唯一出现 1 次的元素,通过 “0 ^ y = y” 被保留在 res 中;
因此,循环结束后,res 就是那个只出现 1 次的元素。
ok,那今天的代码就写到这里了,明天见!
