剑指50.数组中重复的数字

题目描述

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

思路

思路1:排序。将输入的数组排序后判断相邻位置是否存在相同的数字。             (时间复杂度:O(nlogn) ;空间复杂度:O(1))
 
思路2:哈希表。使用HashMap或HashSet。                                                        (时间复杂度:O(n) ;空间复杂度:O(n))
 
--------以下思路3 和 思路4 利用到题中已知条件“数组的长度为 n 且所有数字都在 0 到 n-1 的范围内”---------
 
 
思路3:辅助数组。逐一把原数组A中的每个数字匹配辅助数组B中的下标,首次匹配,B中对应元素+1,如果某次发现B中对应元素不为0,说明重复了。       (不会修改输入数组,但需要用辅助空间, 时间复杂度:O(n) 、空间复杂度:O(n))
 
思路4:交换归位。把扫描的每个数字(如数字m)放到其对应下标(m下标)的位置上,若同一位置有重复,则说明该数字重复。     (不需要辅助空间,但会修改输入数组,  时间复杂度:O(n) 、空间复杂度:O(1))
 
 

解法1(使用哈希表)

import java.util.*;
public class Solution {
    // 使用HashMap
    public boolean duplicate(int numbers[],int length,int [] duplication) {
        if (numbers == null || length == 0)
            return false;
        HashMap<Integer,Integer> map = new HashMap<>();
        for (int num : numbers){
            map.put(num,map.getOrDefault(num,0) + 1);
            if (map.get(num) == 2){
                duplication[0] = num;
                return true;
            }
        }
        return false;
    }
    // 使用HashSet
    public boolean duplicate(int numbers[],int length,int [] duplication) {
        if (numbers == null || length == 0)
            return false;
        HashSet<Integer> set = new HashSet<>();
        for (int num : numbers){
            if (set.contains(num)){
                duplication[0] = num;
                return true;
            }else{
                set.add(num);
            }
        }
        return false;
    }
}

 

解法2(辅助数组)

import java.util.*;
public class Solution {
    public boolean duplicate(int numbers[],int length,int [] duplication) {
        if (numbers == null || length == 0)
            return false;
        int[] room = new int[length];
        //Arrays.fill(room,0);   // 辅助数组初始化为0,不加这句也可以
        for (int i = 0; i < length; i++) {
            if (room[numbers[i]] == 0){
                room[numbers[i]]++;
            }else{
                duplication[0] = numbers[i];
                return true;
            }
        }
        return false;
    }
}

 

☆解法3(交换归位)

public class Solution {
    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){  // 直到当前i位置 == nums[i]
                if (numbers[numbers[i]] == numbers[i]){
                    duplication[0] = numbers[i];
                    return true;
                }else{
                    // swap
                    int temp = numbers[i];
                    numbers[i] = numbers[temp];
                    numbers[temp] = temp;
                }
            }
        }
        return false;
    }
}

 

 
posted @ 2020-09-01 22:11  不学无墅_NKer  阅读(204)  评论(0编辑  收藏  举报