数组中重复的数字
力扣面试题03 : https://leetcode-cn.com/problems/shu-zu-zhong-zhong-fu-de-shu-zi-lcof/
找出数组中重复的数字。
在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。
示例 1:
输入:
[2, 3, 1, 0, 2, 5, 3]
输出:2 或 3
限制:
2 <= n <= 100000
这是剑指offer里面的原题,也是比较简单的一道题,但是,一开始我能想到的就是通过排序然后遍历就能够找到重复的数字,时间复杂度为O(logn),或者通过哈希表建立索引,从而使时间复杂度变为O(n),但是要牺牲额外的空间.然后作者给我们提供了一种很好的方法,我暂且叫做下标定位法.看看是怎么实现的吧
1. 排序实现
直接看代码:
1 | class Solution: |
2. 利用哈希表实现
1 | class Solution: |
3. 下标定位实现
- 阅读题目可以发现,所有数字都在 0~n-1 的范围内(哈哈我感觉其实救赎出题人有意而为), 这就可以假设如果数组中没有重复的数字, 那么排好序之后,数组每一个下标对应的数,其实就是刚好等于下标的,看到这句话,卧槽,牛逼牛逼!!如果有重复的数,则有些下标可能存在多个数,有的下标可能没有数。
- 现在可以重新对这个数组排序,从下标为i开始,这个数字为m,如果m不为i,则将a[i]与a[m]比较,如果不相等,则交换;如果相等,则证明找到了重复的数字。这样,下标为m的数它的值也为m了,相当于每个数最多两次交换就能找到它对应的下标.
1 | class Solution: |
3.1 复杂度分析
时间复杂度:虽然代码中有两层循环,但是每个数最多两次交换就能找到它对应的下标,所以时间复杂度还是为O(n)
空间复杂度:没有用到额外的数据结构,所以空间复杂度为O(1)