【剑指 offer】数组中重复的数字 -- Java 实现

数组中重复的数字

https://www.nowcoder.com/questionTerminal/623a5ac0ea5b4e5f95552655361ae0a8?answerType=1&f=discussion

【剑指 offer】数组中重复的数字 -- Java 实现

一、排序

1. 分析

将输入数组排序,再判断相邻位置是否存在相同数字,如果存在,对 duplication 赋值返回,否则继续比较

2. 代码

import java.util.*;
public class Solution {
    public boolean duplicate(int numbers[],int length,int [] duplication) {
        if(numbers == null || length == 0){
            return false;
        }
        Arrays.sort(numbers);
        for(int i=0;i<length-1;i++){
            if(numbers[i] == numbers[i+1]){
                duplication[0] = numbers[i];
                return true;
            }
        }
        return false;
    }
}

3. 复杂度

时间复杂度:
空间复杂度:

二、哈希表

1. 分析

利用 HashSet 解决,从头到尾扫描数组,每次扫描到一个数,判断当前数是否存在 HashSet 中,如果存在,则重复,对 duplication 赋值返回,否则将该数加入到 HashSet 中

2. 代码

import java.util.*;
public class Solution {
    public boolean duplicate(int numbers[],int length,int [] duplication) {
        Set<Integer> set = new HashSet<>();
        for(int i =0 ;i<length;i++){
            if(set.contains(numbers[i])){
                duplication[0] = numbers[i];
                return true;
            }else{
                set.add(numbers[i]);
            }
        }
        return false;
    }
}

3. 复杂度

时间复杂度:
空间复杂度:

三、利用特性

1. 分析

数组的长度为 n 且所有数字都在 0 到 n-1 的范围内,我们可以将每次遇到的数进行"归位",当某个数发现自己的"位置"被相同的数占了,则出现重复。
扫描整个数组,当扫描到下标为 i 的数字时,首先比较该数字(m)是否等于 i,如果是,则接着扫描下一个数字;如果不是,则拿 m 与第 m 个数比较。如果 m 与第 m 个数相等,则说明出现重复了;如果 m 与第 m 个数不相等,则将 m 与第 m 个数交换,将 m "归位",再重复比较交换的过程,直到发现重复的数

举个栗子:
以数组 {2,3,1,0,2,5,3} 为例
当 i = 0 时,nums[i] = 2 != i,判断 nums[i] 不等于 nums[nums[i]],交换 nums[i] 和 nums[nums[i]],交换后数组为:{1,3,2,0,2,5,3}
此时 i = 0,nums[i] = 1 != i,判断 nums[i] 不等于 nums[nums[i]],交换 nums[i] 和 nums[nums[i]],交换后数组为:{3,1,2,0,2,5,3}
此时 i = 0,nums[i] = 3 != i,判断 nums[i] 不等于 nums[nums[i]],交换 nums[i] 和 nums[nums[i]],交换后数组为:{0,1,2,3,2,5,3}
此时 i = 0,nums[i] = 0 = i,继续下一组
当 i = 1,nums[i] = 1 = i,继续下一组
当 i = 2,nums[i] = 2 = i,继续下一组
当 i = 3,nums[i] = 3 = i,继续下一组
当 i = 4,nums[i] = 2 != i,判断 nums[i] 等于 nums[nums[i]],出现重复,赋值返回

2. 代码

import java.util.*;
public class Solution {
    public boolean duplicate(int nums[],int length,int [] duplication) {
        if(nums == null || length == 0){
            return false;
        }
        for(int i=0;i<length;i++){
            while(nums[i] != i){
                if(nums[i] == nums[nums[i]]){
                    duplication[0] = nums[i];
                    return true;
                }
                // swap
                int tmp = nums[i];
                nums[i] = nums[tmp];
                nums[tmp] = tmp;
            }
        }
        return false;
    }
}

3. 复杂度

时间复杂度:
空间复杂度:

全部评论
排序不对,不能确保输出的是第一个重复的数,有待改进
8 回复 分享
发布于 2020-01-02 17:10
楼主思路没问题,但代码不是最简洁的。还有就是,题目要求返回任意一个重复数字即可,不是第一个,楼上审题似乎不清。
6 回复 分享
发布于 2020-03-12 21:27
方法三有点问题,比如输入用例:[6,3,2,0,2,5,0],输出用例:"true,2",实际却输出:"true,0" 因为结束循环的时候数组变成[0,0,2,3,2,5,6],程序最后走到if(numbers[1] == numbers[numbers[1]])duplication[0] = numbers[1] = 0 时,return ture;结束程序
3 回复 分享
发布于 2020-10-28 22:39
[2,1,1,2],排序之后第一个重复的数字是1而不是2,需要改进
2 回复 分享
发布于 2020-01-08 16:39
第一种和第三种都是错的
2 回复 分享
发布于 2020-03-09 16:50
最后一个方法确实不对,他和书上的一样,可以输出重复的数字,但是没有办法保证是第一个重复的数字
2 回复 分享
发布于 2021-01-21 20:43
排序的时间复杂度为O(n)吧
1 回复 分享
发布于 2020-02-05 11:58
最后一个方法,不能检测出 这种[2, 1, 3, 3, 4]的重复数字,但是官方也给通过。。。
1 回复 分享
发布于 2019-12-22 22:50
剑指offer书中题意是输出任意一个重复的数字,但此题输出“第一个重复”的数字,所以方法一和三在这里都不对
1 回复 分享
发布于 2021-01-07 23:52
用哈希的思想有更好的解决方法 复杂度为O(N) public boolean duplicate(int numbers[],int length,int [] duplication) { if(numbers==null||numbers.length==0) return false; int[] tmp = new int[length]; for(int i=0;i<length>1) { duplication[0]=numbers[i]; return true; } } return false; }</length>
点赞 回复 分享
发布于 2019-10-15 14:59
最后一个方法不行,在某些情况下,例如int[] ints = {1,6,7,0,2,3,4,7,6}; 返回的不是第一个出现的重复数字
点赞 回复 分享
发布于 2019-10-23 21:25
[3,3,3,4,4]这种情况最后一种方法返回4,实际应该返回3
点赞 回复 分享
发布于 2019-12-23 18:56
没问题啊,没有要求第一个
点赞 回复 分享
发布于 2020-04-02 17:19
while那里如果数组中没有0是不是出不去啊?
点赞 回复 分享
发布于 2020-04-02 20:31
好像懂了。。。
点赞 回复 分享
发布于 2020-04-02 21:01

相关推荐

10-17 12:16
同济大学 Java
7182oat:快快放弃了然后发给我,然后让我也泡他七天最后再拒掉,狠狠羞辱他一把😋
点赞 评论 收藏
分享
shtdbb_:还不错,没有让你做了笔试再挂你
点赞 评论 收藏
分享
97 2 评论
分享
牛客网
牛客企业服务