给定一个整数数组,除了for之外,每个元素都会出现两次 一。找到那一个。
注意: 您的算法应具有线性运行时复杂性。你可以在不使用额外内存的情况下实现吗?
class Solution:
# @param {integer[]} nums
# @return {integer}
def singleNumber(self, nums):
prev = []
for i,j in enumerate(nums):
if j in prev:
nums[i] = -j
else:
prev.append(j)
return sum(nums)
这是来自leetcode的问题,实际上是AC率最高的问题。但是,正如我的代码所说,它告诉我时间限制已超出并且无法被接受。任何人都可以分析我的代码,包括复杂性吗?非常感谢。
Upadate: 谢谢大家,我已将“prev”从列表更改为一组,这很好用!
class Solution:
# @param {integer[]} nums
# @return {integer}
def singleNumber(self, nums):
prev = set([])
for i,j in enumerate(nums):
if j in prev:
nums[i] = -j
else:
prev.add(j)
return sum(nums)
然而,正如问题所描述的那样,我仍在寻找不需要额外记忆的解决方案。
更新: 我用另一种方法试图解决问题,但再次收到超过时间。
class Solution:
# @param {integer[]} nums
# @return {integer}
def singleNumber(self, nums):
for i,j in enumerate(nums):
if j in set(nums[:i+1]):
nums[i] = -j
return sum(nums)
实际上我有点困惑,像nums [:i + 1]这样的切片会在每个循环中创建一个单独的列表吗?那么创建列表最耗时吗?我使用set而不是list,这样可以降低搜索成本。
答案 0 :(得分:5)
@彼得的答案很棒:
def singleNumber(nums):
unique = 0
for num in nums:
unique ^= num
return unique
答案 1 :(得分:3)
Xor是要走的路。 两个相似元素的Xor为0,因此所有重复都将消失,导致res中存在非重复元素。
x=[1,1,2,3,2,4,4,5,5]
res=x[0]
for i in xrange(1,len(x)):
res^=x[i]
print res
答案 2 :(得分:3)
这是编写XOR解决方案的另一种功能性方法。
from operator import xor
def single_number(nums):
return reduce(xor, nums)
在Python 3.x中,(显然Leetcode不使用),您需要从reduce
模块导入functools
函数。
答案 3 :(得分:0)
你可以使用cython(我现在第二次使用它,所以可能还有改进):
使用以下内容创建文件singleNumber.pyx
:
def singleNumber(list nums, int nn):
cdef int i, ii, np
cdef list prev = []
for i in xrange(nn):
np = len(prev)
for ii in xrange(np):
if nums[i] == prev[ii]:
nums[i] = - prev[ii]
else:
prev.append(nums[i])
return sum(nums)
使用以下内容创建文件setup.py
:
from distutils.core import setup
from Cython.Build import cythonize
setup(
ext_modules=cythonize('singleNumber.pyx'),
)
编译:{{1}}
python setup.py build_ext --inplace
结果:import singleNumber as sn
arr = [i + 1 for i in range(1000)]
%timeit sn.singleNumber(arr,len(arr))
使用100000 loops, best of 3: 15.4 µs per loop
函数可以给我:XOR
编辑:
如果我使用10000 loops, best of 3: 82.1 µs per loop
解决方案与原始函数相比,我会得到不同的结果!
XOR
给我:from operator import xor
def singleNumber_xor(nums):
return reduce(xor, nums)
arr = [i + 1 for i in range(10000)]
singleNumber_xor(arr)
原始功能:
10000
给我:def singleNumber_orig(nums):
prev = set([])
for i,j in enumerate(nums):
if j in prev:
nums[i] = -j
else:
prev.add(j)
return sum(nums)
singleNumber_orig(arr)