leetcode 学习分享——2 寻找重复数
最近焦虑于校招,所以开始刷leetcode,刷到比较有用的心得就记录下来,大家共享~
话不多说直接上题号:287。
给定一个包含 n + 1 个整数的数组 nums,其数字都在 1 到 n 之间(包括 1 和 n),可知至少存在一个重复的整数。假设只有一个重复的整数,找出这个重复的数。
示例:
输入: [1,3,4,2,2]
输出: 2
解题思路:
首先分析一下这道题,我们是要找到数组中重复的数字,那么简单思考一下就知道,对于最坏的情况我们怎么也要遍历一遍数组,所以时间复杂度最低也要达到 O ( n ) O(n) O(n)。
那么在只遍历一遍的情况下,我们有哪些方法呢?最先想到的就是hashmap了。
hashmap
简而言之,哈希表就是一个字典,key是输入的数组中的元素,value就是是否出现过,遍历数组的时候维护这个哈希表,如果找到某个元素在哈希表中出现过了,则返回该值。
扩展的话就是对于找到所有有重复的或者说不重复的元素,那么就遍历哈希表去找到对应value值的所有key值就好。
但是这个解法的问题在于空间复杂度很高,达到了 O ( n ) O(n) O(n),那么如果这个数组很大的时候,对于内存的需求就会爆表,所以对于空间复杂度的优化就显得很重要了。
所以接下来的这个位图解法就问世了。
bitmap
位图的解法的核心思想就是用一些隐藏的资源来表示我们想要的数据,以此来减少空间的使用。
举例来说,对于我们上述题目的示例来说, b i t m a p bitmap bitmap 的初始化就是一个整数,表示目前还没有任何数字出现过。判断 n n n 这个数字是否出现过就可以通过访问 b i t m a p bitmap bitmap 的第 n n n 位来获得这个数字在数组中出现的次数。
接下来通过遍历数组就可以维护这个 b i t m a p bitmap bitmap 了,当发现对于某个 n n n , b i t m a p bitmap bitmap 的第 n n n 位 不是 0 0 0的时候,说明这个 n n n 在遍历数组的时候已经访问到了,所以返回这个 n n n 即为这道题的解。
具体做法有两步:
Case 1:如果将
b
i
t
m
a
p
bitmap
bitmap 向右移位
n
n
n 步长之后的最后一位是1的话(bitmap >> num & 1),说明该数出现过了,返回该数。
Case 2:如果将 b i t m a p bitmap bitmap 向右移位 n n n 步长之后的最后一位是0的话(bitmap >> num & 1),说明该数没有出现过,所以将 b i t m a p bitmap bitmap 的对应位置置为1(bitmap += 1<<num)。
这个算法的时间复杂度并没有变,仍然是遍历一遍数组,但是空间复杂度从 O ( n ) O(n) O(n) 变成了 O ( 1 ) O(1) O(1),因为这个 b i t m a p bitmap bitmap 只是一个整数变量,在python语言下,long型的变量是没有最大值限制的。
至此,寻找重复数问题得解。
代码
最后上代码:
class Solution:
def findDuplicate(self, nums: List[int]) -> int:
bitmap = 0
for num in nums:
if bitmap >> num & 1:
return num
else:
bitmap += 1<<num
以及结果截图
希望大家有什么意见在评论区多交流,如果在接下来的学习过程中有新的想法也会及时和大家分享。
下期再见喽~