算法题:找出1到1亿中“只有一个重复的”自然数
三种解题算法思路:
方式一:先将数组排序,然后判断是否存在相邻的两个数
缺点:数组排序这个操作消耗cpu内存,性能差劲,面试官直接pass的 ||-||
方式二:使用递归折半方式进行查找
缺点:遍历的次数太多,耗时太长
方式三:先求1到1亿之和,只需要遍历一次数组,每次用和减去数组中的值,剩余的值就是多余的自然数
优点:目前想到最好的方式
下面提供几种方式的解题代码:
# coding=utf-8
import time
list0 = [i for i in range(100000000 + 1)]
list0.insert(123456, 78769) # 随机插入一个数据
# 时间统计装饰器
def time_print(f): # 输入是函数,输出也是函数
def wrapper(*arg): # 固定参数
start = time.time()
ret = f(*arg)
print(time.time() - start)
return ret
return wrapper
@time_print
def fun1(arr):
'''排序之后,判断相邻数方式'''
arr.sort()
for i in range(len(arr) + 1):
if arr[i] == arr[i + 1]:
return i
print(fun1(list0)) # 5秒多
def fun2(arr, start, mid, end):
"""
折半遍历,遍历的次数太多,耗时太长
"""
if mid >= end or mid <= start:
return mid
j = 0
for i in arr:
if i < mid:
j += 1
if j > mid:
return fun2(arr, start, (start + mid)/2, mid)
return fun2(arr, mid, (mid + end)/2, end)
start = time.time()
print(fun2(list0, 0, len(list0)/2, len(list0))) # 48秒
print(time.time() - start)
@time_print
def fun2(list1):
total = (1 + 100000000) * 50000000
# total = sum(i for i in range(100000000 + 1)) # 耗时太大
for i in list1:
total -= i
return total
print(fun2(list0)) # 3秒多