概述
查找只出现一次的数
- 题目描述
- 代码
- 方法一:二分查找,效率高,时间复杂度为O(logn)
- 写法1(优化之前,初步思路,步骤详细,方便理解)
- 写法2(精简之后的写法)
- 程序运行展示
- 方法二:其他方法,时间复杂度太高,不太可取
题目描述
给定一个非空整数有序数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
这是我面试BAT其中某家广告算法工程师时的面试题,首先应该考虑的是时间复杂度和空间复杂度,且是有序数组,我首先想到的是二分查找,时间复杂度为O(logn)。
代码
方法一:二分查找,效率高,时间复杂度为O(logn)
写法1(优化之前,初步思路,步骤详细,方便理解)
import pysnooper
list1 = [1,1,2,2,3,4,4,5,5,6,6]
@pysnooper.snoop()#pysnooper是装饰器,可以修改函数,作用是打印函数的参数
def fun(list1):
if len(list1)==0:#判读是否是空列表
return -1
elif len(list1)==1:#判读是否只有一个元素
return list1[0]
elif list1[0]!=list1[1]:#判读该数是否出现在最左边
return list1[0]
elif list1[-1]!=list1[-2]:#判读该数是否出现在最右边
return list1[-1]
else:#正常情况
low = 0
hi = len(list1)-1
while min!=low:
m = int((low+hi)/2)#取中间位置
if m%2 == 0:
if list1[m]==list1[m+1]:
low = m#扔掉一半元素
else:
hi = m#扔掉一半元素
if list1[m]!=list1[m-1] and list1[m]!=list1[m+1]:
return list1[m]
else:
if list1[m]==list1[m-1]:
low = m#扔掉一半元素
else:
hi = m#扔掉一半元素
if list1[m]!=list1[m-1] and list1[m]!=list1[m+1]:
return list1[m]
return list1[m]
写法2(精简之后的写法)
import pysnooper
list1 = [1,1,2,2,4,5,5,6,6]
@pysnooper.snoop()#pysnooper是装饰器,可以修改函数,作用是打印函数的参数
def fun(list1):
list1 = ['a','a']+list1+ ['b','b']
list1.append('a')
low = 0
hi = len(list1)-1
while min!=low:
m = int((low+hi)/2)#取中间位置
if (m%2 == 0 and list1[m]==list1[m+1]) or (m%2 == 1 and list1[m]==list1[m-1]):
low = m#扔掉右边一半元素
else:
hi = m#扔掉左边一半元素
if list1[m]!=list1[m-1] and list1[m]!=list1[m+1]:
return list1[m]
return list1[m]
print(fun(list1))
程序运行展示
Starting var:.. list1 = [1, 1, 2, 2, 4, 5, 5, 6, 6]
11:31:49.977043 call 4 def fun(list1):
11:31:49.978044 line 5 list1 = ['a','a']+list1+ ['b','b']
Modified var:.. list1 = ['a', 'a', 1, 1, 2, 2, 4, 5, 5, 6, 6, 'b', 'b']
11:31:49.978044 line 6 list1.append('a')
Modified var:.. list1 = ['a', 'a', 1, 1, 2, 2, 4, 5, 5, 6, 6, 'b', 'b', 'a']
11:31:49.978044 line 7 low = 0
New var:....... low = 0
11:31:49.978044 line 8 hi = len(list1)-1
New var:....... hi = 13
11:31:49.978044 line 9 while min!=low:
11:31:49.978044 line 10 m = int((low+hi)/2)#取中间位置
New var:....... m = 6
11:31:49.978044 line 11 if (m%2 == 0 and list1[m]==list1[m+1]) or (m%2 == 1 and list1[m]==list1[m-1]):
11:31:49.978044 line 14 hi = m#扔掉左边一半元素
Modified var:.. hi = 6
11:31:49.978044 line 15 if list1[m]!=list1[m-1] and list1[m]!=list1[m+1]:
11:31:49.978044 line 16 return list1[m]
11:31:49.978044 return 16 return list1[m]
Return value:.. 4
方法二:其他方法,时间复杂度太高,不太可取
list1 = [1,1,2,2,4,5,5]
def fun2(list1):
k = min(set(list1),key = list1.count)
print(k)
#结果:4
最后
以上就是谨慎期待为你收集整理的算法题:查找只出现一次的数 两种方法 二分查找 时间复杂度为O(logn)题目描述代码的全部内容,希望文章能够帮你解决算法题:查找只出现一次的数 两种方法 二分查找 时间复杂度为O(logn)题目描述代码所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复