题目描述
找出数组中重复的数字。
在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。
示例 1:
输入:
[2, 3, 1, 0, 2, 5, 3]
输出:2 或 3
限制:
2 <= n <= 100000
解答
最直接的做法就是用HashMap,时间和空间都是O(n)。
然而,注意题目中说明了,数组的长度为n,数字都在 0~n-1 的范围内,那么我们就可以省略HashMap的空间了。
如果没有重复的元素,那么我们可以调整数组的元素的位置,使下标为i的位置上元素的值就是i。
那如果元素有重复呢?我们的做法是,遍历数组,尝试让下标为i的位置上元素的值就是i,
- 如果nums[i] == i,则跳过当前元素;
- 如果nums[i] != i,则令temp值等于当前元素nums[i],让nums[temp]与nums[i]进行交换,这样一来nums[temp]上的元素值就是temp,但是nums[i]上的元素值仍未必等于i,所以要循环操作,直到nums[i] == i。但在交换之前,如果已经存在nums[temp] == temp,那么说明temp就是重复的。
时间复杂度直接看的话并不明显,但因为程序每次都在把元素放回对应的位置,所以应该是时间O(n),空间O(1)。
执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户
内存消耗:47.6 MB, 在所有 Java 提交中击败了100.00%的用户
代码如下:
public class Solution {
public int findRepeatNumber(int[] nums) {
int temp;
for (int i = 0; i < nums.length; i++) {
while (nums[i] != i) {
temp = nums[i];
if (nums[temp] == temp) {
return temp;
}
nums[i] = nums[temp];
nums[temp] = temp;
}
}
return -1;
}
}