LeetCode-136-只出现一次的数字
题意描述:
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
说明:你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
示例:
示例一 :
输入: [2,2,1]
输出: 1
示例二:
输入: [4,1,2,1,2]
输出: 4
解题思路:
Alice: 这题我会,把数组排个序,相同的数字肯定是相邻的,只要有一个数字和它后面的那个数字不相等,那这个元素肯定就是那个独一份的。
Bob: Wonderful, 但是排序算法最快也得是O(n log n)的吧,肯定不是线性的,说不定会超时。
Alice: 我试了,没有超时,O(∩_∩)O哈哈~
Bob: 没有超时也肯定有更简单的写法!!
Alice: 那你倒是写啊?
Bob: 我有一个想法,我们可以先取数组中所有数字的集合,然后集合里面的元素求和 再乘2 再减去原有的数组的和 就是那个元素了。
Alice: 不错嘛,但是取数组中所有数字的集合应该也不是线性的吧,除非求集合的时候用了哈希映射。
Bob: 是哦,我们看看别人怎么写的吧.
Alice: 我已经看了,用了位运算,把两个相同的元素放在一起变成零了。
Bob: 异或运算符,二进制位上相同的为0,不同的为1, x ^ x == 0,原来是这样。我怎么没想到呢!
Alice: 你做的题还不够多。
Bob: 你说的对,冰冻三尺非一日之寒,驽马十驾,功在不舍。
代码:
方法1:
class Solution:
def singleNumber(self, nums: List[int]) -> int:
nums.sort()
#print(nums)
for x in range(0, len(nums), 2):
if x == len(nums) - 1:
# 为了防止越界访问数组,如果只出现一次的数字在末尾就需要单独判断一下。
return nums[-1]
if nums[x] != nums[x+1]:
return nums[x]
方法2:
class Solution:
def singleNumber(self, nums: List[int]) -> int:
return 2 * sum(list(set(nums))) - sum(nums)
方法3 的Python版本:
class Solution:
def singleNumber(self, nums: List[int]) -> int:
ret = 0
for x in nums:
ret ^= x
return ret
方法3的Java版本:
class Solution {
public int singleNumber(int[] nums) {
int answer = 0;
for(int i=0; i<nums.length; ++i){
answer = answer ^ nums[i];
}
return answer;
}
}
易错点:
- LeetCode上非线性时间的方法也能过,不知道真正笔试的时候会是怎样的。
总结:
位运算: 异或,二进制数按位异或,相同为零,不同为一。2 ^ 2 == 0