找出不是两个数组共有的元素_你能用多少种方法解决剑指 offer 的第 3 号算法题:数组中重复的数字...

bf68a89c87769622418a083a963771d4.png

问题描述

找出数组中重复的数字。

给你一个长度为 n 的数组 nums,它具有如下的特点:

  1. 数组中的每个元素的值在 0 ~ n - 1 的范围内
  2. 数组中存在重复的元素,但是我们不知道重复的元素重复了几次

请找出数组中任意一个重复的元素。

示例:

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

限制:2 <= n <= 100000

方案一:暴力求解

暴力求解的思路非常的直接:

  • 遍历数组中的每个元素,然后在剩下的元素中寻找是否存在相同的元素

代码如下:

public 

以上算法实现的复杂度分析:

  • 时间复杂度是 O(n^2)
  • 空间复杂度是 O(1)

细心的朋友应该会发现这道题目描述的最后对 n 做了一个限制,也就是:

2 <= n <= 100000

那就是说,数据规模 n 有可能是 10 万级别的,如果时间复杂度是 O(n^2) 的话,那么数据规模就会变成 10 万的平方了,这个级别就高了,所以上面的代码的性能是非常差的。接下来我们来优化。

方案二:哈希查找

在暴力解法中,我们先遍历每一个元素,然后再从其余的元素中查找这个元素是否存在,其实这里要的就是能高效的判断一个元素是否已经存在,我们可以使用哈希表,因为哈希表判断是否存在的时间复杂度是 O(1)。

使用哈希表后的算法步骤是:

  1. 先初始化一个哈希表 (HashSet)
  2. 然后遍历每一个元素,分别对每一个元素做如下的处理:
    1. 先判断哈希表中是否存在这个元素
    2. 如果存在的话,则说明这个元素重复,则直接返回
    3. 否则,将这个元素加入到哈希表中,方便后续的判重

代码如下:

public 

以上算法实现的复杂度分析:

  • 时间复杂度是 O(n)
  • 空间复杂度是 O(n)

时间复杂度 O(n),对于数据规模 10 万级别的话,运行速度是可以接受的。但是这里的空间复杂度则变为 O(n),因为哈希表需要申请额外的 n 个空间,这里用到的是典型的空间换时间的思想

方案三:数组代替哈希表

在题目中,有一个信息,我们需要注意下,那就是数组中每个元素的大小在 0 ~ n - 1 的范围内。利用这个信息,我们就可以使用数组代替上面方案二的哈希表,主要的思路是:

  • 定义一个长度为 n 的数组 bucket,然后将所有的元素初始化为 -1
  • 在查找处理的时候,使用原数组的元素作为 bucket 的下标,原数组元素对应的下标作为 bucket 的元素值。

我们直接看代码:

public 

以上算法实现的复杂度分析:

  • 时间复杂度是 O(n)
  • 空间复杂度是 O(n)

可以看出,时间复杂度和空间复杂度都是和用哈希表的解决方案是一样的。但是使用数组绝对会有性能的提高,主要表现在如下的两个方面:

  1. 哈希表 (HashSet) 底层是使用数组 + 链表或者红黑树组成的,而且它的数组也是用不满的,有加载因子的。所以使用数组来代替哈希表,能节省空间
  2. 哈希表在判重的时候需要经过哈希计算,还可能存在哈希冲突的情况,而使用数组则可以直接计算得到 index 的内存位置,所以使用数组访问性能更好。

注意:如果上面的代码还是看不懂的话,建议先看下面的视频。

方案四:最优解法

以上的解法是最优的吗?还能不能优化呢?请看下面的视频。

知乎视频​www.zhihu.com

代码如下:

public 

以上算法实现的复杂度分析:

  • 时间复杂度是 O(n)
  • 空间复杂度是 O(1)

可以看出,我们利用这种方法,空间复杂度降到了 O(1) 了。

谢谢你的阅读和收听,如果你觉得这篇文章对你有帮助的话,你可以分享给你的朋友哟~

这篇文章,首发于公众号:抖码课堂

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值