推荐

完整《剑指Offer》算法题解析系列请点击 👉 《剑指Offer》全解析 Java 版

题目描述

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

public class Solution {
   
    // Parameters:
    // numbers: an array of integers
    // length: the length of array numbers
    // duplication: (Output) the duplicated number in the array number,length of duplication array is 1,so using duplication[0] = ? in implementation;
    // Here duplication like pointor in C/C++, duplication[0] equal *duplication in C/C++
    // 这里要特别注意~返回任意重复的一个,赋值duplication[0]
    // Return value: true if the input is valid, and there are some duplications in the array number
    // otherwise false
    public boolean duplicate(int numbers[],int length,int [] duplication) {
   
    
    }
}

思路:

因为长度为 n 的数组中保存的是 0到n-1的范围内的数字,那么我们只需要把数字依次放到数组中对应下标的位置上即可,当找到第一个对应位置上已经有相同数字的,就是我们要找的第一个重复的数字。

比如:数组 nums{3, 1, 2, 1}

第一次下标为0:
nums[0] == 3, 不等于 0 ,

我们将 nums[0] 与 nums[3] 比较,nums[0] != nums[3] ,我们交换 nums[0] 与 nums[3],

得到 nums{1, 1, 2, 3};

这个时候,nums[0] == 1,还是不等于0.

我们将 将 nums[0] 与 nums[1] 比较,nums[0] == nums[1] ,找到了第一个重复的数字。

实现:

public class Solution {
   
    // Parameters:
    // numbers: an array of integers
    // length: the length of array numbers
    // duplication: (Output) the duplicated number in the array number,length of duplication array is 1,so using duplication[0] = ? in implementation;
    // Here duplication like pointor in C/C++, duplication[0] equal *duplication in C/C++
    // 这里要特别注意~返回任意重复的一个,赋值duplication[0]
    // Return value: true if the input is valid, and there are some duplications in the array number
    // otherwise false
    public boolean duplicate(int numbers[],int length,int [] duplication) {
   
        //排除数组长度小于等于的情况
        if(length <= 0){
   
            return false;
        }
        //排除数组中的数字小于0 或者 大于数组长度的情况
        for(int x : numbers){
   
            if(x < 0 || x >= length)
                return false;
        }
        
        //遍历数组
        for(int i=0;i<length;i++){
   
            //一直交换,直到 numbers[i] == i ,或者找到第一个重复的数字。
            while(numbers[i] != i){
   
                //如果对应位置上的数重复了,则找到了第一个重复的数字
                if(numbers[i] == numbers[numbers[i]]){
   
                    //将结果存到结果数组中。
                    duplication[0] = numbers[i];
                    return true;
                }
                //如果与对应位置上的数不重复,则交换位置,将i上的数字放到对应位置上去。
                int temp = numbers[i];
                numbers[i] = numbers[temp];
                numbers[temp] = temp;
                
            }    
        }
        //如果遍历完数组都没找到重复的数字,则返回false。
        return false;
    }
}

看完之后,如果还有什么不懂的,可以在评论区留言,会及时回答更新。

这里是猿兄,为你分享程序员的世界。

非常感谢各位大佬们能看到这里,如果觉得文章还不错的话, 求点赞👍 求关注💗 求分享👬求评论📝 这些对猿兄来说真的 非常有用!!!

注: 如果猿兄这篇博客有任何错误和建议,欢迎大家留言,不胜感激!