python找出数组中重复的数字_剑指offer-3数组中重复的数字-python

《剑指offer》python实现系列,全目录

题目一

在一个长度为 n 的数组里的所有数字都在 0~m-1 的范围内。数组中某

些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了

几次。请找出数组中任意一个重复的数字。例如,如果输入长度为 7 的数组{2,3,1,0,2,5,3},那么对应的输出是重复的数字 2 或者 3。

最初想法

最简单的方法是遍历数组,

优化:创建一个长度为n的辅助数组temp,读取原数组值x,令temp[x]=1,再读入新元素检测是否为1即可。

使用辅助数组

1

2

3

4

5

6

7

8

9def duplicate( numbers, duplication):

temp = [0]*len(numbers)

for i in numbers:

if temp[i] == 1:

duplication[0] = i

return True

temp[i] = 1

return False

不使用辅助数组:【官方】

直接在原数组上交换元素,确保元素与其下标相等。

详细思路:看书上的例子p39

1

2

3

4

5

6

7

8

9def duplicate( numbers, duplication):

for i in range(len(numbers)):

while i != numbers[i]:#保证元素与下标i对应

if numbers[numbers[i]] == numbers[i]: #如果已经有元素

duplication[0] = numbers[i]

return True

else:

numbers[numbers[i]], numbers[i] = numbers[i], numbers[numbers[i]] #交换位置

return False

我的方法

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14#还是利用下标,将nums[i]位置的元素乘以-1

class Solution(object):

def findRepeatNumber(self, nums):

"""

:type nums: List[int]

:rtype: int

"""

for i in range(len(nums)):

temp = abs(nums[i])

if nums[temp] < 0:

return temp

else:

nums[temp] = -nums[temp]

return 0#如果到底也没return,那一定是0乘-1了

题目二

不修改数组,不利于辅助空间,找出重复数字

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

利用二分查找

我们以长度为 8 的数组{2,3,5,4,3,2,6,7}为例分析查找的过程。根据题目要求,这个长度为 8 的所有数字都在 17 的范围内。中间的数字 4 把 17 的范围分为两段,一段是 14, 另一段是 57。接下来我们统计 1 -4 这 4 个数字在数组中出现的次数,它们一共出现了 5 次,因此这 4 个数字中一定有重复的数字。

接下来我们再把 1~4 的范围一分为二,一段是 1、2 两个数字,另一段是 3、4 两个数字。数字 1 或者 2 在数组中一共出现了两次。我们再统计数字 3 或者 4 在数组中出现的次数,它们一共出现了三次。这意味着 3、4 两个数字中一定有一个重复了。我们再分别统计这两个数字在数组中出现的次数。接着我们发现数字 3 出现了两次,是一个重复的数字。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24class Solution(object):

def findRepeatNumber(self, nums):

"""

:type nums: List[int]

:rtype: int

"""

n = len(nums)

start =1

end = n-1

while start<=end:

mid = (start+end)//2

count = 0

for elem in nums:

if start <= elem <= mid:

count += 1

if end == start:

if count >1:

return start

if count > (mid-start)+1:#重复元素在【start与mid区间】

end = mid

else:

start = mid+1

return mid

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值