对应LeetCode上的题目:面试题03. 数组中重复的数字
题目描述:在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字
题目描述
在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字
解法一,暴力求解法
先把输入的数字排序,从排序的数字中找出重复的数字,即需要从头到尾扫描排序后的数组就可以了,排序一个长度为 n 的数组需要 O(nlogn) 的时间(排序最快的速度是 O(nlogn) ,即快速排序)
1 | const findRepeatNumber = (nums) => { |
可想而知,这种解法并不是那么令人满意,因为需要先把数组排序
解法二,使用对象
使用对象来解决这个问题,从头到尾遍历整个数组,依次把数组的每一项当作对象的 key 值存进对象。如果数组的某个项在对象中存在,那么我们就可以认为这个值在数组中重复了,直接返回即可
1 |
|
解法三,数学分析法
从头到尾遍历数组
当数组下标为
i的时候,比较这个数字(用m表示)是不是等于i,如果是,则接着扫描下一个数字。如果不是,拿它与第
m个数字进行比较。如果它和第m个数字相等,就找到了一个重复的数组(i和m的位置上都存在数字m)。如果它和第m个数字不相等,就把第i个位置上的数字和第m个位置上的数字交换,那么 第m位上的数字就是m了重复这个比较,直到发现一个重复的数字
[2, 3, 1, 0, 2, 5, 3] 举个例子:
首先遍历这个数组,从
0位置上开始遍历。0上面的数字是2,那么我们可以直接拿数字2和2位置上的1做比较,结果不相等,交换位置。交换之后的数组是 [1, 3, 2, 0, 2, 5, 3]此时
0位置上面的数字是1,仍然不相等,继续和下标为1的 数字3做交换。交换之后的数组是 [3, 1, 2, 0, 2, 5, 3]此时
0位置上面的数字是3,仍然不相等,继续和下标为3的 数字0做交换。交换之后的数组是 [0, 1, 2, 3, 2, 5, 3]这时候
0位置上的数字是0了,那么我们可以直接遍历下一个数字了,可知接下来的数字1,2,3都与坐标相等,不用进行交换操作。接下来到位置
4的数字2,由于数字与位置不相等,再比较位置2上的数字。发现位置2上的数字也是2了,因此我们便找到了一个重复的数字
1 |
|
