leetcode剑指offer面试题03数组中重复的数字java题解(鸽巢原理)

1.题目
找出数组中重复的数字。
在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。
示例 1:
输入:[2, 3, 1, 0, 2, 5, 3]
输出:2 或 3
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/shu-zu-zhong-zhong-fu-de-shu-zi-lcof
2.题解
(1)没有任何要求的
HashMap:

HashMap<Integer,Integer> mp=new HashMap<Integer,Integer>();
        for(int i=0;i<nums.length;i++){
    
    
          if(mp.containsKey(nums[i])){
    
    int temp=mp.get(nums[i]);temp++;mp.put(nums[i],temp);}
          else{
    
    mp.put(nums[i],1);}
        }
        for(Integer i:mp.keySet()){
    
    
          if(mp.get(i)>1){
    
    return i;}
        }
        return -1;

排序

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

(2)不修改数组
在创建一个新数组,对每个出现的数字进行统计,若有大于1的,立即返回(鸽巢原理)

class Solution {
    
    
    public int findRepeatNumber(int[] nums) {
    
    
        int[] result = new int[nums.length];

        for(int j=0;j<result.length;j++) {
    
    
          result[j]=-1;
        }

        for(int i = 0; i < nums.length; i++) {
    
    
            if(nums[i]==result[nums[i]]) {
    
    
                return nums[i];
            } else {
    
    
                result[nums[i]]=nums[i];
            }
        }
       return -1;
    }
}

(3)不修改数组,且原地O(1)
先找到数组总长度的中间数,在中间数的左边或者右边统计一个有多少个数字,若大于中间数则说明该边存在重复数,然后循环缩小范围,直至找到重复数。(此题好像不可以用,书里有这种算法)
3.效率
(1)鸽巢原理效率最高
在这里插入图片描述

(2)Hash
在这里插入图片描述
(3)排序
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/zeshen123/article/details/105141114