剑指 Offer 03. 数组中重复的数字

剑指 Offer 03. 数组中重复的数字

对于此题,可以有几种不同的考虑,如果可以看出这是一类频率统计题,容易联系到哈希表,所以第一种方法也是比较容易想到的办法就是用哈希表来统计词频,这里由于数据范围可确定(0-n-1),可以用数组来简化一些代码上的书写,这种方法时间复杂度为\(O(n)\),空间复杂度为\(O(n)\)

class Solution {
    public int findRepeatNumber(int[] nums) {
        int n = nums.length;
        if (n == 0) {
            return 0;
        }
        int[] map = new int[n];
        for(int num : nums) {
            map[num]++;
            if(map[num] > 1) return num;
        }
        return 0;
    }
}

以上是基于词频的角度考虑,再考虑不需要新空间的算法,若我们将数组排序,如果有重复的数字,那么它们将会在相邻位置,同样可以做到找出重复数字的目的。时间复杂度\(O(nlogn)\),空间复杂度\(O(1)\)

class Solution {
    public int findRepeatNumber(int[] nums) {
        Arrays.sort(nums);
        for (int i = 1; i < nums.length; i++) {
            if (nums[i] == nums[i - 1])
                return nums[i];
        }
        return -1;
    }
}

再考虑空间复杂度为\(O(1)\)且时间复杂度能够更低的算法。
我们可以发现给定的数据范围为\(0-n-1\)。若我们将对应的索引放置在它的对应位置,如果没有重复元素,那么每个元素都会被放在它的索引位置,如果有重复元素,则放置时会发现该位置已经有元素了。

class Solution {
public int findRepeatNumber(int[] nums) {
int n = nums.length;
for(int i = 0; i < n; i++) {
while(nums[i] != i) {
if(nums[nums[i]] == nums[i]) return nums[i];
int tmp = nums[i];
nums[i] = nums[tmp];
nums[tmp] = tmp;
}
}
return -1;
}
}

posted @ 2022-01-18 23:04  NullPointer_C  阅读(41)  评论(0)    收藏  举报