136. 只出现一次的数字
题目
-
给你一个 非空 整数数组 nums ,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
你必须设计并实现线性时间复杂度的算法来解决此问题,且该算法只使用常量额外空间。
示例 1:
输入:nums = [2,2,1]
输出:1
示例 2:
输入:nums = [4,1,2,1,2]
输出:4
示例 3:
输入:nums = [1]
输出:1
法一、排序加遍历
- 思路:先对数组进行排序,然后遍历数组,每次跳过出现两次的元素。当找到一个元素与下一个元素不相等时,即找到了只出现一次的元素。
class Solution:
def singleNumber(self, nums: List[int]) -> int:
nums = sorted(nums)
for i in range(len(nums)-1):
if nums[i] != nums[i+1]:
return(nums[i])
i+=1#错误,应该一次跳过两个元素
-
第一次解决时,没通过,很多地方没考虑到:应该一次跳过两个元素;数组只有一个元素的情况未考虑到;只出现一次的元素在最后一个位置的情况
-
如果找到了只出现一次的元素,就直接返回该元素。如果整个循环结束后仍未找到只出现一次的元素,说明只出现一次的元素在数组的末尾,因此我们返回 nums[-1]。
class Solution:
def singleNumber(self, nums: List[int]) -> int:
nums.sort() # 先对数组进行排序
n = len(nums)
i = 0
while i < n:
if i == n - 1 or nums[i] != nums[i + 1]:#数组只有一个元素或者找到不相等的元素时
# 当前元素与下一个元素不相等,即找到了只出现一次的元素
return nums[i]
i += 2 # 跳过出现两次的元素
# 如果只出现一次的元素在数组末尾
return nums[-1]
- 时间复杂度为 O(nlogn)。
法二、异或性质
- 异或运算:
任何数和自己做异或运算,结果为0,即 a ^ a=0
任何数和0做异或运算,结果还是自己,即 a ^ 0=a
异或运算中,满足交换律和结合律,也就是 a ^ b ^ a=b ^ a ^ a=b ^ (a ^ a)=b ^ 0=b。
class Solution:
def singleNumber(self, nums: List[int]) -> List[int]:
x = 0
for num in nums: # 1. 遍历 nums 执行异或运算
x ^= num
return x # 2. 返回出现一次的数字 x
时间复杂度O(N):线性遍历nums使用O(N)时间,异或操作使用O(1)时间
空间复杂度O(1):辅助变量a,b,x,y使用常数大小额外空间
法三、reduce()函数
class Solution:
def singleNumber(self, nums: List[int]) -> List[int]:
return reduce(operator.xor, nums)#xor表示异或
- reduce()函数会对参数序列中元素进行累积,接收的参数:一个函数 f,一个list,实例如下:
from functools import reduce
def add(x, y) : # 两数相加
return x + y
sum1 = reduce(add, [1,2,3,4,5]) # 计算列表和:1+2+3+4+5
sum2 = reduce(lambda x, y: x+y, [1,2,3,4,5]) # 使用 lambda 匿名函数
print(sum1) #15
print(sum2) #15
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人