• 【剑指offer】3-数组中重复的数字


    【仅用于个人学习记录分享,非商业用途】

    ————————————————————————————————————————

    题目一描述

    在一个长度为 n 的数组里的所有数字都在 0 到 n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字是重复的,也不知道每个数字重复几次。请找出数组中任意一个重复的数字。

     Input:
     {2, 3, 1, 0, 2, 5}
     
     Output:
     2

    题目解析

    对于这种数组元素在 [0, n-1] 范围内的问题,可以将值为 i 的元素调整到第 i 个位置上进行求解。本题要求找出重复的数字,因此在调整过程中,如果第 i 位置上已经有一个值为 i 的元素,就可以知道 i 值重复。

    解题代码

     class Solution:
         def duplicate(self, numbers, duplication):
             if numbers == None or len(numbers)<=1:
                 return False
             for i in range(len(numbers)):
                 if numbers[i]<0 or numbers[i]>len(numbers)-1:
                     return False
             for i in range(len(numbers)):
                 while(numbers[i] !=i):
                     if numbers[i] == numbers[numbers[i]]:
                         duplication[0] = numbers[i]
                         return True
                     else:
                         temp = numbers[i]
                         numbers[i] = numbers[temp]
                         numbers[temp] = temp
             return False

    题目二 不修改数组找出重复的数字

    描述

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

    题目解析

    解题思路:找到规律“在1-n的范围内只有n个数字,如果超过n个数字,则一定包含重复的数字”

    基于此思想,将数组长度n的1-n的数字分为m两部分,前一半为1-m,后一半为m+1~n.如果1-m的数字范围的数字,在数组中出现的个数大于m,则在这一半有重复数字,则在此范围内进行查找,相反则在另外一半查找。

    题目理解

    此题使用的是二分法的变体,可以理解为一种夹逼思想。先对数字范围进行分组,然后在两个分组中再进行查找。注意这里分组的不是要查找的数组,而是数组长度的范围。通过不断的缩小数字范围得到结果,而数组只是用来统计数字出现的次数。

    代码实现

     class Solution:
         def duplicate(self, numbers):
             if not numbers or len(numbers)<0:
                 return -1
             start = 1
             end = len(numbers)-1
             while start<=end: #注意这是左右闭合的写法
                 middle = (end - start)//2 + start
                 count = self.countRange(numbers, len(numbers), start, middle)
                 if end == start:
                     if count >1:
                         return start
                     else:
                         break
                 if count > middle - start +1: #如果数字i-m范围出现次数大于m-i+1,则此范围数字有重复
                     end = middle
                 else:
                     start = middle +1
              return -1
      def countRange(self, numbers, length, start, end):
      if not numbers:
                 return 0
             count = 0
             for i in range(lenght):
                 if numbers[i]>= start or numbers[i] <= end:
                     count+=1
                 return count
  • 相关阅读:
    一文带你彻底明白如何实现动态添加子节点及修改子节点属性
    一文带你彻底理解 JavaScript 原型对象
    Oracle内存占用高过时的调整策略
    Oracle Instant Client(即时客户端) 安装与配置
    windows环境完全卸载Oracle19c
    Oracle19c常用语句
    cannot mount database in EXCLUSIVE mode解决办法
    oracle存储过程通过游标输出Sql结果集
    Oracle DBlink的创建
    MySQL语法
  • 原文地址:https://www.cnblogs.com/szxyx/p/13307756.html
Copyright © 2020-2023  润新知