数组中重复的数字

来源:互联网 发布:实参数组类型 编辑:程序博客网 时间:2024/05/29 07:32

题目描述:

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

答案:

# 方法一:借助辅助空间,输出全部重复的数字import numpy as nparray = np.array([2,3,1,0,2,5,3,3])def repeat(array):    b = []    length = len(array)    for i in range(length):        if array[i] in b:            # 返回已经存在的值            yield array[i]        b.append(array[i])c = set(repeat(array))print(c) #{2,3}# 输出重复数字重复的次数# c1 = list(repeat(array))# for i in c:#     print(c1.count(i))

# 方法二:对原数组排序,遍历排序后的数组import numpy as nparray = np.array([2,3,1,0,2,5,3])def repeat(array):    length = len(array)    for i in range(length):        for j in range(i+1,length):            if array[j]<array[i]:                tmp = array[i]                array[i] = array[j]                array[j] = tmp    # print(array)排序后的数组    for i in range(length):        if i != array[i]:            return array[i]c = repeat(array)print(c) #{2}


# 方法三:牛客网可通过代码'''从头到尾依次扫描这个数组中的每个数字。当扫描到下标为i的数字时,首先比较这个数字(用m表示)是不是等于i。如果是,则接着扫描下一个数字;如果不是,则再拿它和第m个数字进行比较。如果它和第m个数字相等,就找到了一个重复的数字(该数字在下标i和m的位置都出现了);如果它和第m个数字不相等,就把第i个数字和第m个数字交换,把m放到属于它的位置。接下来重复这个比较、交换的过程,直到我们发现一个重复的数字。'''# -*- coding:utf-8 -*-class Solution:    def duplicate(self, numbers, duplication):        length = len(numbers)        if length == None:            return False        for index in range(length):            if numbers[index]<0 or numbers[index]>length-1:                return False        for index in range(length):            while index != numbers[index]:                if numbers[index] == numbers[numbers[index]]:#不同位置有相同值                    duplication[0] = numbers[index]                    return True                tmp = numbers[index]                numbers[index] = numbers[tmp]                numbers[tmp] = tmp        return False


#方法四import collectionsdef repeat(numbers):    c = collections.Counter(numbers)    for k,v in c.items():        if v>1:            return knumbers = [1,1,1,2,2,3,4]print(repeat(numbers))


题目变形:

在一个长度为n+1的数组里的所有数字都在1~n的范围内,所以数组中至少有一个数字是重复的。请找出数组中任意一个重复的数字,但是不能修改输入的数组。例如,如果输入长度为8的数组{2,3,5,4,3,2,6,7},那么对应的输出是重复的数字2或者3。

'''我们把从1~n的数字从中间的数字m分为两部分,前面一半为1~m,后面一半为m+1~n。如果1~m的数字的数目等于m,则不能直接判断这一半区间是否包含重复的数字,反之,如果大于m,那么这一半的区间一定包含重复的数字;如果小于m,另一半m+1~n的区间里一定包含重复的数字。接下来,我们可以继续把包含重复的数字的区间一分为二,直到找到一个重复的数字。这个过程和二分查找算法很相似,只是多了一步统计区间里数字的数目。二分查找对象序列为1~n的有序序列,如题目中例子对应的二分查找序列为{1,2,3,4,5,6,7}'''# 统计一定范围内有序序列元素在输入数组中出现的次数def countRange(numbers,start,end):    if numbers == []:        return 0    count = 0    length = len(numbers)    for i in range(length):        if numbers[i]>=start and numbers[i]<=end:            count+=1    return countdef repeat(numbers):    if numbers == []:        return -1    length = len(numbers)    start = 1    end = length-1    while start <= end:        middle = (end+start)//2        count = countRange(numbers,start,middle)        if end == start:            if count>1:                return start            else:                break        if count>(middle-start+1):            end = middle        else:            start = middle+1    return -1a = [2,3,5,4,3,2,6,7]print(repeat(a))#3

上面的代码针对0~n-1的数组不适用,对其改进

def countRange(numbers,start,end):    if numbers == []:        return 0    count = 0    length = len(numbers)    for i in range(length):        if numbers[i]>=start and numbers[i]<=end:            count+=1    return countdef repeat(numbers):    if numbers == []:        return -1    length = len(numbers)    start = 0    flag = 0    end = length-1    while start <= end:        if flag == 0:            middle = start+((end-start)>>1)        count = countRange(numbers,start,middle)        if end == start:            if count>1:                return start            else:                break        if count>(middle-start+1):            end = middle            flag = 0        elif count == (middle - start + 1):            middle = middle - 1            if middle < start: #说明(start, middle)这个区间没有重复的数                start = (start+end) // 2 + 1                flag = 0            else:                flag = 1        else:            start = middle+1            flag = 0    return -1a = [1,7,2,5,6,1,3,3]b = [2,3,5,4,3,2,6,7]print(repeat(b))




原创粉丝点击