题目
找出数组中重复的数字。
在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。
利用Set解决
时间复杂度为O(N)
import java.util.HashSet;
import java.util.Set;
/**
* 剑指 Offer 03. 数组中重复的数字
* @Author laimouren
* @Date 2021/12/11 18:50
*/
public class Solution {
public int findRepeatNumber(int[] nums) {
Set<Integer> set = new HashSet<>();
for (int n:nums) {
if(set.contains(n)){
return n;
}
set.add(n);
}
return -1;
}
}
原地交换法
K神解法:
题目说明尚未被充分使用,即 在一个长度为 n 的数组 nums 里的所有数字都在 0 ~ n-1 的范围内 。 此说明含义:数组元素的 索引 和 值 是 一对多 的关系。
因此,可遍历数组并通过交换操作,使元素的 索引 与 值 一一对应(即 nums[i] = inums[i]=i )。因而,就能通过索引映射对应的值,起到与字典等价的作用。
class Solution {
public int findRepeatNumber(int[] nums) {
int i = 0;
while (i < nums.length){
//此时是下标为i的元素的值刚好为i,
//即元素已经在合适的位置,不需要在做交换
if(nums[i] == i){
i++;
continue;
}
//当此时下标为nums[i]的元素已经是nums[i]时,
//证明之前已经有元素是nums[i],返回即可
if(nums[nums[i]] == nums[i]){
return nums[i];
}
//交换下标为nums[i]的元素和下标为i的元素,
//使num[i]位置的元素为num[i]
int temp = nums[i];
nums[i] = nums[temp];
nums[temp] = temp;
}
return 0;
}
}
时间复杂度 O(N):遍历数组使用O(N) ,每轮遍历的判断和交换操作使用 O(1)
空间复杂度 O(1):使用常数复杂度的额外空间。