剑指 Offer 03. 数组中重复的数字 #原地交换 #O(1)空间复杂度

353 阅读1分钟

找出数组中重复的数字。

在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。

题目分析

找出重复的数字很简单,遍历放进Set就得到答案了,但是很明显这不是题目想要的答案。题中给出了一个限定条件

长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内

0 ~ n-1,这不刚好就是数组的索引范围,于是利用这个条件可以有如下解法:

假设我们把所有的数字都放在与其对应的索引处,如果没有重复数字,那么刚好每个每个索引处对应的都是与其索引相等的值,而如果有重复的数字,那么当我们要把这个重复的数字放在与其对应的索引处时,会发现此时该索引处已经存储了与其索引相等的值了,至此,我们就找出了一个重复的数字。

函数设计

image-20220727211150007

代码

class Solution {
    public int findRepeatNumber(int[] nums) {
        for (int i = 0; i < nums.length;) {
            if (nums[i] == i) {
                i++;
                continue;
            }
            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) **:使用常数复杂度的额外空间

\