剑指offer第3:数组中重复的数字

题目描述

在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2。

# -*- coding:utf-8 -*-
class Solution:
    # 这里要特别注意~找到任意重复的一个值并赋值到duplication[0]
    # 函数返回True/False
    def duplicate(self, numbers, duplication):
        # write code here
        if len(numbers)<=1:
            return False
        i=0
        while i<=len(numbers):
            m=numbers[i]
            if m==i:
                i+=1
            else:
                if numbers[i]==numbers[m]:
                    return True 
                    
                else :
                    temp=numbers[i]
                    numbers[i]=numbers[m]
                    numbers[m]=temp
                i+=1
        return False

题目2:题目描述: 
在一个长度为n+1的数组里的所有数字都在1~n的范围内,所以数组中至少有一个数字是重复的。请找出数组中任意一个重复的数字,但是不能修改输入的数组。

def find_dux_num(seq):
    if len(seq) <= 1 or seq is None:
        return None

    start, end = 1, len(seq) - 1  # 获取数字1,n

    while start <= end:
        mid = (start+end) // 2  # 获取中间数字
        count = count_num(seq, start, mid)  # 计算[start, mid]数字之间的数目

        # 当只取到一个数字时,如果该数字出现数目大于1,就是重复数字
        if start == end:
            if count > 1:
                return start
            else:
                break

        # 如果count数目 > 中间数字到起始数字之差,一定存在重复数字,继续在这一段中求中间数比较
        if count > mid - start + 1:
            end = mid
        # 否则在后一段中求中间数比较
        else:
            start = mid + 1

    return None


def count_num(seq, start, end):
    count = 0
    for i in seq:
        if start <= i <= end:
            count += 1
    return count


if __name__ == '__main__':
    print(find_dux_num([1, 2, 3, 4, 3]))

作者:大白杏仁
链接:https://www.jianshu.com/p/b35c528e01d7
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

https://www.jianshu.com/p/b35c528e01d7 有详细的介绍

这种方法虽然不需要辅助空间O(n),但是后面每半个区间都需要遍历整个数组,函数countNum将被调用O(logn)次,每次需要O(n)的时间,因此总的时间复杂度是O(nlogn),空间复杂度为O(l)。相当于用时间换空间了。 
现在来总结下关于数组中重复数字的问题,利用辅助空间的话,时间和空间复杂度都是O(n);利用下标于数字对应关系的话时间复杂度是O(n),空间复杂度是O(l),但是需要改变数组;利用二分查找类似思路的方法,时间复杂度是O(nlogn),空间复杂度O(l),所以要问清楚面试官他想要空间效率高的呢?还是时间效率高的呢?能不能改变数组呢?一方面体现交流能力,一方面能最快的写出答案。

还剩一个辅助空间法。

猜你喜欢

转载自blog.csdn.net/zhangjiaxuu/article/details/81276496
今日推荐