美文网首页
剑指 offer 笔记 50 | 数组中重复的数字

剑指 offer 笔记 50 | 数组中重复的数字

作者: ProudLin | 来源:发表于2019-11-14 09:08 被阅读0次

题目描述
在一个长度为 n 的数组里的所有数字都在 0 到 n-1 的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。

也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为 7 的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字 2。

思路分析
对于这种数组元素在 [0, n-1] 范围内的问题,可以将值为 i 的元素调整到第 i 个位置上进行求解。也就是归位,当某个数发现自己的"位置"被相同的数占了,则出现重复。

1)扫描整个数组,当扫描到下标为 i 的数字时,首先比较该数字(m)是否等于 i,如果是,则接着扫描下一个数字;

2)如果不是,则拿 m 与第 m 个数比较。

3)如果 m 与第 m 个数相等,则说明出现重复了;如果 m 与第 m 个数不相等,则将 m 与第 m 个数交换,将 m "归位",再重复比较交换的过程,直到发现重复的数

以 (2, 3, 1, 0, 2, 5) 为例,遍历到位置 4 时,该位置上的数为 2,但是第 2 个位置上已经有一个 2 的值了,因此可以知道 2 重复:

最终时间复杂度 O(N),空间复杂度 O(1)。

解释说明:

public boolean duplicate(int[] numbers, int length, int[] duplication) {
    if (numbers== null || length <= 0)//判空处理
        return false;
    for (int i = 0; i < length; i++) {
        while (numbers[i] != i) {  //是否众神归位
            if (numbers[i] == numbers[numbers[i]]) {//是否位置被人占了
                duplication[0] = numbers[i];
                return true;
            }
            swap(numbers, i, numbers[i]);//交换归位
        }
    }
    return false;
}

private void swap(int[] numbers, int i, int j) {
    int t = numbers[i];
    numbers[i] = numbers[j];
    numbers[j] = t;
}

https://www.nowcoder.com/questionTerminal/623a5ac0ea5b4e5f95552655361ae0a8?answerType=1&f=discussion
来源:牛客网

相关文章

网友评论

      本文标题:剑指 offer 笔记 50 | 数组中重复的数字

      本文链接:https://www.haomeiwen.com/subject/sdwtictx.html