0%

数组中重复的数字


题目:

题解:

1、哈希表 / Set

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// 使用set.contains方法判断
class Solution2 {
public int findRepeatNumber(int[] nums) {
HashSet set = new HashSet();
for (int num:
nums) {
if (set.contains(num)) {
return num;
}else set.add(num);
}
return -1;
}
}

// 使用set集合中不能有重复的特性
class Solution3 {
public int findRepeatNumber(int[] nums) {
Set<Integer> set = new HashSet<Integer>();
int repeat = -1;
for (int num : nums) {
if (!set.add(num)) {
repeat = num;
break;
}
}
return repeat;
}
}
  • 复杂度分析:
    • **时间复杂度 O(N)**: 遍历数组使用 O(N) ,HashSet 添加与查找元素皆为 O(1)。
    • **空间复杂度 O(N)**: HashSet 占用 O(N) 大小的额外空间。

2、原地交换

  • 解题思路:

    • 可遍历数组并通过交换操作,使元素的 索引 与 值 一一对应(即 nums[i]=i )。因而,就能通过索引映射对应的值,起到与字典等价的作用。
    • 遍历中,第一次遇到数字 x 时,将其交换至索引 x 处;而当第二次遇到数字 x 时,一定有 nums[x]=x ,此时即可得到一组重复数字。
  • 代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    // 原地交换
    class Solution4 {
    public int findRepeatNumber(int[] nums) {
    int i = 0;
    while(i < nums.length){
    // 说明此数字已在对应索引位置,无需交换,因此跳过
    if (nums[i] == i) {
    i++;
    continue;
    }
    // 判断索引为nums[i]的是否与索引为i的相等,相等说明索引nums[i]已经有与nums[i]的值相等的了,即有重复的了
    if (nums[nums[i]] == nums[i]) return nums[i];
    int tmp = nums[i];
    nums[i] = nums[tmp];
    nums[tmp] = tmp;
    }
    return -1;

    }
    }
  • 复杂度分析

    • **时间复杂度 O(N)**: 遍历数组使用 O(N) ,每轮遍历的判断和交换操作使用 O(1)。
    • **空间复杂度 O(1)**: 使用常数复杂度的额外空间。