找出数组中重复的数字。

373 阅读1分钟
在一个长度为n的数组的所有数字都在1~n-1的范围内。数组中某些数字是重复的,但不知道有哪几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出应该是重复的数字2或者3。

除了排序数组遍历找出重复的数字(时间复杂度为nLogn),以及创建一个哈希表(时间复杂度O(1)空间复杂度O(n))两个方法外。还可以有别的方法,综合时间复杂度与空间复杂度来看比前面两个方法更优。

由于限定了数字的最大值不会超过数组长度,可以从头到尾依次扫描数组中每个数字,当下标i与数组下标为i的值(记为m)不相等时,如果arr[m]与arr[arr[m]]两个值相等,则找到了重复数字,否则交换下标为m的数字与下标为i的数字。如果相等则继续扫描下一个。

代码实现如下:

function duplicate(arr){
    if(!(arr instanceof Array)) return;   
    const length = arr.length;
    if(length===0) return;
    for(let i of arr){
        if(i<0||i>length-1){
            return false;
        }     
    }

    for(let i=0;i<length;i++){
        while(arr[i]!=i){
            if(arr[i] == arr[arr[i]]){
                return arr[i];
            }else{
                var tmp = arr[i];
                arr[i] = arr[tmp];
                arr[tmp] = tmp;
            }
        }
    }
    return false; 
}

虽然有两重循环,但是每个数字最多只要交换两次就能找到属于自己的位置,所以时间复杂度为O(n),不需要额外分配空间,空间复杂度为O(1)。