剑指offer03.数组中重复的数字
剑指offer03.数组中重复的数字
- 题目
- 第一种解法
- 第二种解法
- 第三种解法
- 值得一提的东西
题目
在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。
示例 1:
输入: [2, 3, 1, 0, 2, 5, 3]
输出:2 或 3
第一种解法
一个简单的暴力方法就是先把输入的数组排序.从排序的数组中找出重复的数字是一件容易的事情,只需要判断一个数字的下一个数字是否与本身相等即可
.但是排序一个长度为n的数组需要O(nlogn)的时间
时间复杂度较高,不可取
第二种解法
使用哈希表来解决这个问题.从头到尾按顺序扫描这个数组的每个数字.
每扫描到一个数字的时候.都可以用O(1)的时间来判断哈希表中是否存在了这个数字. 如果哈希表中没有这个数字就把他加入进去,下次再判断时就能找出来
时间复杂度 : O(n)
空间复杂度 : O(n)提高了时间复杂度的前提下是牺牲了一个大小为O(n)的哈希表为代价的
第三种解法
有没有一种空间上为O(1)的更高效的解法呢?
在一个长度为 n 的数组 nums 里的所有数字都在 0 ~ n-1 的范围内 。
此说明含义:数组元素的 索引 和 值 是 一对多 的关系。
因此,可遍历数组并通过交换操作,使元素的 索引 与 值 一一对应(即 nums[i] = i )。因而,就能通过索引映射对应的值,起到与字典等价的作用。
遍历中,第一次遇到数字 x 时,将其交换至索引 x 处;而当第二次遇到数字 x 时,一定有 nums[x] = x ,此时即可得到一组重复数字。
算法流程:
遍历数组 nums ,设索引初始值为 i=0 :
若 nums[i]=i : 说明此数字已在对应索引位置,无需交换,因此跳过;
若 nums[nums[i]] = nums[i] : 代表索引 nums[i] 处和索引 ii 处的元素值都为 nums[i] ,即找到一组重复值,返回此值 nums[i] ;
否则: 交换索引为 i 和 nums[i] 的元素值,将此数字交换至对应索引位置。
若遍历完毕尚未返回,则返回 −1 。
值得一提的东西
测试用例可能包含无效测试用例
如输入长度为n的数组中包含(0~n-1)之外的数字
传入空数组等等
所以我们需要先进行参数的校验合法性
总结
以上是生活随笔为你收集整理的剑指offer03.数组中重复的数字的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: 超详细C语言的字符串函数讲解
- 下一篇: 剑指offer06.从尾到头打印链表