只出现一次的数字
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
说明:
你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
用内置函数统计就是最赖皮的:
class Solution:
def singleNumber(self, nums: List[int]) -> int:
for n in nums:
if nums.count(n) == 1:
return n
但是上面的方法耗时太严重,最快的就是异或运算啦!出现两次的元素异或后为0,最后的运算结果就是只出现过一次的。
class Solution:
def singleNumber(self, nums: List[int]) -> int:
res = 0
for n in nums:
res = res ^ n
return res
官方代码也是异或,只写了一行,真简洁👍
class Solution:
def singleNumber(self, nums: List[int]) -> int:
return reduce(lambda x, y: x ^ y, nums)
只出现一次的数字Ⅱ
给你一个整数数组 nums ,除某个元素仅出现 一次 外,其余每个元素都恰出现 三次 。请你找出并返回那个只出现了一次的元素。
赖皮且无意义解法,耗时是真的多!
class Solution:
def singleNumber(self, nums: List[int]) -> int:
for n in nums:
if nums.count(n) == 1:
return n
评论区的数学/电路大佬靠着强大的数学能力,利用与或非等将出现三次的元素运算为0,实在是妙!
一开始a = 0, b = 0;
x第一次出现后,a = (a ^ x) & ~b的结果为 a = x, b = (b ^ x) & ~a的结果为此时因为a = x了,所以b = 0。
x第二次出现:a = (a ^ x) & ~b, a = (x ^ x) & ~0, a = 0; b = (b ^ x) & ~a 化简, b = (0 ^ x) & ~0 ,b = x;
x第三次出现:a = (a ^ x) & ~b, a = (0 ^ x) & ~x ,a = 0; b = (b ^ x) & ~a 化简, b = (x ^ x) & ~0 , b = 0;所以出现三次同一个数,a和b最终都变回了0.
只出现一次的数,按照上面x第一次出现的规律可知a = x, b = 0;因此最后返回a.
class Solution:
def singleNumber(self, nums: List[int]) -> int:
a, b = 0, 0
for n in nums:
a = (a ^ n)& ~b
b = (b ^ n)& ~a
return a
快了两倍多,也没有使用额外空间,绝了!
只出现一次的数字Ⅲ
给定一个整数数组 nums,其中恰好有两个元素只出现一次,其余所有元素均出现两次。 找出只出现一次的那两个元素。你可以按 任意顺序 返回答案。
进阶:你的算法应该具有线性时间复杂度。你能否仅使用常数空间复杂度来实现?
无用代码又有了。。。我有罪
class Solution:
def singleNumber(self, nums: List[int]) -> List[int]:
if len(nums) == 2:
return nums
res = []
for n in nums:
if nums.count(n) == 1:
res.append(n)
return res
就很耗时。
节省时间的话,还是以异或运算为基础,最后的结果则为两个只出现一次的元素的异或结果。任取一位为 1 的位数,两个数有一个为 1 ,一个为 0 。再次遍历,将 nums 分为两组,分别求出两个元素。
class Solution:
def singleNumber(self, nums: List[int]) -> List[int]:
if len(nums) == 2:
return nums
tem = 0
for n in nums:
tem ^= n
pos = 1
while pos&tem == 0:
pos <<= 1
a, b = 0, 0
for n in nums:
if n & pos:
a ^= n
else:
b ^= n
return [a, b]
绝了!
第一个只出现一次的字符
类似题,只不过是处理字符串
在字符串 s 中找出第一个只出现一次的字符。如果没有,返回一个单空格。 s 只包含小写字母。
class Solution:
def firstUniqChar(self, s: str) -> str:
for char in s:
if s.index(char) == s.rindex(char):
return char
return " "
字符串的内置函数就是比 list 丰富。
class Solution:
def firstUniqChar(self, s: str) -> str:
hashmap = collections.Counter(s)
for i, char in enumerate(hashmap):
if hashmap[char] == 1:
return char
return " "
使用哈希表,找到第一个频率为 1 的元素即可。