Day1数组中的重复数字

这篇博客介绍了如何在数组中找出重复的数字,提供了两种方法:一是利用哈希表(set)进行查找,二是通过原地交换元素实现。对于长度为n且数字范围在0~n-1的数组,哈希表方法的时间复杂度为O(N),空间复杂度为O(N);原地交换方法的时间复杂度同样为O(N),空间复杂度为O(1)。博主分享了代码实现并探讨了Python中交换元素的注意事项。
摘要由CSDN通过智能技术生成

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

示例:

输入:
[2, 3, 1, 0, 2, 5, 3]
输出:2 或 3 

限制:

2 <= n <= 100000

方法一:哈希表 / set

算法流程:

  1. 遍历数组,将不在hashTable里的数字添加到里面去。
  2. 如果数字在hashTable里则返回该数字。

时间复杂度:O(N),遍历数组O(N) , 添加查找均是O(1)

空间复杂度: O(N) , hashTable占用了大小O(N)的额外空间

代码实现(python)

class Solution:
    def findRepeatNumber(self, nums: List[int]) -> int:
        hashTable = set()
        for num in nums:
            if(num in hashTable):
                return num
            hashTable.add(num)

💬set(集合) 和 dict(字典)类似 , 是一组key的集合,但是不存储value,且里面的key是唯一的。

添加元素 add(key) 删除元素 remove(key)


方法二:原地交换

数组的长度为n , 里面的整数在0~n-1的范围内,并且有元素重复,也就是说重复数字和索引是一对多的关系,我们可以遍历数组,使索引和元素的值一一对应,从而起到和字典一样的作用。

算法流程:

  1. 从索引 i = 0 开始,如果 nums[i] != i ,将nums[i] 与nums[nums[i]]交换位置。
  2. 当nums[i] = i 时 , i + 1
  3. 如果 nums[i] == nums[nums[i]] ,说明在’字典‘中有这个数,即重复数字,返回该数字

时间复杂度:O(N) ,遍历数组O(N),交换和查找均为O(1)

空间复杂度:O(1) , 使用常数复杂度的额外空间

代码实现:

class Solution:
    def findRepeatNumber(self, nums: List[int]) -> int:
    	i = 0
        while i < len(nums):
            if nums[i] == nums[nums[i]]:return nums[i]
            if nums[i] == i:
                i += 1			#注意python没有i++
                continue
            nums[nums[i]],nums[i] = nums[i],nums[nums[i]]
            
    		

nums[nums[i]],nums[i] = nums[i],nums[nums[i]]

这里的交换要注意python的内存机制,它是先开辟新的空间——一个集合来存放括号右边的两个数,再从左到右赋值到左边,不能写成 nums[i],nums[nums[i]] = nums[nums[i]],num[i],否则 nums[i]先变化,那么 nums[nums[i]]里的索引就变了。


由于刚开始刷题不久,写题解是为了理解得更深刻一些,并且记录一下自己犯的错误

本篇参考了leetcode上@Krahets大佬的题解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端corner

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值