剑指offer----数组中重复数字 以及 不修改数组找出重复的数字

数组中重复数字问题的三种思路

第一种思路:排序后遍历,时间复杂度o(nlogn),空间复杂度o(1)

def duplication(array):
    array.sort()
    for i in range(len(array)):
        if i==len(array)-1:
            return False
        if array[i]==array[i+1]:
            topic=array[i]
            return topic
    return False

if __name__=='__main__':
    array=[1,32,3,5,3]
    res=duplication(array)
    print(res)

第二种思路:哈希表,时间复杂度o(n),空间复杂度o(n)

def duplication(array):
    array_dict={}
    for arr in array:
        if arr not in array_dict:
            array_dict[arr]=0
        else:
            topic=arr
            return topic
    return False
if __name__=='__main__':
    array=[1,32,3,5,3]
    res=duplication(array)
    print(res)

第三种思路:题目中提到数组范围为0到n-1,利用现有数组设置标志。时间复杂度o(n),空间复杂度o(1)

def duplication(array):
    flag = len(array)
    for i in range(len(array)):
        index = array[i] % flag if array[i] >= flag else array[i]
        if array[index] > flag:
            topic = index
            return topic
        array[index] += flag
    return False

if __name__=='__main__':
    array=eval(input())
    res=duplication(array)
    print(res)

不修改数组找出重复的数字
时间复杂度o(nlogn),空间复杂度o(1),相当于以时间换空间。

#二分法查找统计思想
#数值范围1-n,一共n-1个数字
#循环实现,循环改变索引值进行二分:
def getDuplication(a):
    m = len(a)
    startN = 1      #列表数值范围最小值
    endN = m      #列表数值范围最大值

    while startN <= endN:
        midN = (startN+endN)>>1     #二分法中间值
        numbers = 0
        for i in range(m):
            if (a[i]<= midN) & (a[i]>= startN):
                numbers += 1
        if numbers > (midN - startN+1):     #关键(midN - startN+1),如果没有重复元素,startN与midN范围间相差的数字个数
            startN, endN = startN, midN
        else:
            startN, endN = midN+1, endN
        if startN == endN:                  #最后判断数组出现的次数
            number = 0
            for j in a:
                if j ==startN:
                    number += 1
            if number > 1:
                return startN
            else:
                break
    return False
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值