zoukankan      html  css  js  c++  java
  • 1、找出数组中重复的数字

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

    解法一:先对数组进行排序,然后再查找排序后的数组中的重复元素

    def selectedSort(lis):
    for i in range(0, len(lis)):
            minVal = lis[i]
            minInd = i
            #找出最小的元素
            for j in range(i+1,len(lis)):
                if minVal>=lis[j]:
                    minVal=lis[j]
                    minInd=j
            #交换
            lis[minInd]=lis[i]
            lis[i]=minVal
        return lis
    lis=[8,5,3,3,7,6,3,9,1,8]
    lis_order=selectedSort(lis)
    print(lis)

    解法二:开辟一个新数组B,每次扫描源数组A中的元素,如果不在B中,就加入B中,如果在B中,就找到一个重复的元素

    lisA=[8,5,3,3,7,6,3,9,1,8]
    def findDuplicates(lisA):
        lisB = []
        for i in lisA:
            if i in lisB:
                print("找到一个重复的元素:%d"%i)
                break
            else:                   #当前扫描的元素不在lisB中,就加入到lisB中
                lisB.append(i)
                continue
    findDuplicates(lisA)

    解法三:因为列表总共有n个元素,所有元素可能取到的元素有0~n-1,共n种。如果不存在重复的数字,那么排序后数字i将会出现在下标为i的位置。现在让我们重新扫描数组,

    • 当扫描到下标为i的数字时,首先比较这个数字(记为m)与i是否相等:
      • 如果是,继续扫描下一个元素,
      • 如果不是,则再拿它与第m个数字比较:
        • 如果它和第m个数字相同,就找到了一个重复的元素;
        • 如果不同,就将m与第m个数字互换。接下来继续重头开始,重复换这个比较。
    lisA=[8,0,2,3,7,6,4,2,1,5]
    def findDuplicates(lisA):
    
        i=0
        while i <len(lisA) and lisA!=[]:
            m = lisA[i]
            if m == i:    
                i += 1
            else:
                if m == lisA[m]:
                    print('找到一个重复的元素:%d' % m)
                    break
                else:
                    temp = lisA[i]
                    lisA[i] = lisA[m]
                    lisA[m] = temp
                    i = 0
    
    findDuplicates(lisA)

    题目二:

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

    解法一:同上题解法二,开辟一个大小为n+1的新数组

    解法二:避免使用O(n)的辅助空间。我们把取值空间[1,n]从中间的数字m分为两部分,前面一部分为1~m,后面一部分为m+1~n。如果数组中元素落在前面一部分的元素个数多于m个,那么数组中重复的元素一定落在前半区间;否则,数组中重复的元素一定落在后半区间。然后,我们可以继续将包含重复元素的区间一分为二,直到找到一个重复的元素。

    lisA=[8,1,2,3,7,6,7,4,9,5,10]
    
    def findDuplicates(lisA):
        """找到重复元素,返回True;否则,返回False"""
        low=1
        high=len(lisA)-1
    
        while low<=high:
            mid=(low+high)//2
    
            #统计数组中落在前半部分区间中的元素的个数
            count_low=0
            for i in lisA:
                if i in range(low,mid+1):
                    count_low+=1
    
            #判断落在长度为1的区间中的数组元素个数
            if high==low:
                if count_low>1:                 #如果大于1,则找到重复的元素
                    return low
                else:
                    break
    
            #比较前半部分区间长度与落在该区间内元素的个数,决定将前半部分/后半部分区间继续一分为二
            if count_low>(mid-low+1):
                high=mid
            else:
                low=mid+1
    
        return False
    
    print(findDuplicates(lisA))
  • 相关阅读:
    2017年11月01日普及组 I Got a Matrix!
    2017年10月21日普及组 简单单词
    2017年10月21日普及组 排名
    2017年10月18日普及组 文件名排序
    2017年10月18日普及组 面积最大
    2017年10月08日 上学
    [APIO2010]特别行动队
    斜率优化DP(学习笔记)
    [HNOI2008]玩具装箱TOY
    皇宫看守
  • 原文地址:https://www.cnblogs.com/zijidan/p/9511235.html
Copyright © 2011-2022 走看看