算法题:找出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秒多

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值