这是我在解答leetcode第136题时的感悟,这是一到简单题,解答其实不难,但要满足题目要求的线性时间复杂度和不使用额外空间就有点难了,在这道题的解答中,“异或”会让你见识到什么叫神操作。
136. 只出现一次的数字
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
说明:
你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
示例 1:
输入: [2,2,1]
输出: 1
示例 2:
输入: [4,1,2,1,2]
输出: 4
解题思路
这道题考查的是逻辑运算,与或非操作相信大家都比较熟悉,但异或操作很多人还是不太会的,比如我,刚上手这道题时我是傻傻的将数组转list然后遍历一次数组,若list.remove(Object(nums[i]))返回false就list.add(nums[i]);其实这样做的代码量是很精简的,但用到了额外空间,且运行时间…大概是五百多毫秒,有点丢人。而学废“异或”之后,just 1ms时间、1行关键代码,简直是神操作。
对于异或(Java中的异或操作符为^),我们只需要掌握三条基本性质:
1.a ^ 0=a
2.a ^ a=0
3.a ^ b ^ c=b ^ c ^ a
于是可以推出a ^ b ^ a=b,那这个题不就迎刃而解了吗!直接将所有数字异或连接,double的数字会被异或为0,single的数字则会被保留,具体实现看代码:
class Solution {
public int singleNumber(int[] nums) {
int i=1;
while(i<nums.length){
nums[0]^=nums[i++];
}
return nums[0];
}
}