zoukankan      html  css  js  c++  java
  • 剑指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;
        }
    }
     
  • 相关阅读:
    poj 2391 Ombrophobic Bovines
    混合欧拉回路poj 1637 Sightseeing tour
    POJ1149-PIGS
    C
    B
    A
    C
    B
    A
    O
  • 原文地址:https://www.cnblogs.com/HuangYJ/p/13598864.html
Copyright © 2011-2022 走看看