找出从1~n连续整数中的重复数字只有一个是重复的

找出1~1000中的重复数字,其中只有一个是重复的

题目

找出1~1000中的重复数字,其中只有一个是重复的

思路

方法1:HashMap实现

遍历数组把每个数存入到HashMap中ifMap不存在就存入else直接跳出循环时间复杂度为O(N)遍历数组空间复杂度为O(N).

下面就看代码实现:

  public static int getDuplicateNum(int[] arr){
       if (arr.length==0) return -1;
        HashMap<Integer,Integer> map=new HashMap<>();
        int res=0;
        for (int i = 0; i <arr.length ; i++) {
            if (!map.containsKey(arr[i])){
                map.put(arr[i],i);
            }else {
                res=arr[i];
                break;
            }
        }
            return res;
}

能不能不申请额外的空间呢?

方法2:累加求和法

求出0~1000的和和遍历数组求和之后相减即可求出重复的数字

下面就看代码实现:

 public static int getDuplicateNum(int[] arr){
  	if (arr.length==0) return -1;
        int sum=0,arrsum=0;
        for (int j=0;j<1000;j++){
            sum+=j;
        }
        for (int i = 0; i <arr.length ; i++) {
            arrsum+=arr[i];
        }
        return arrsum-sum;
    }

此方法有缺陷就是如果数组的和超出了int的范围就不适合了有没有更适合的方法呢?

方法3:或异法

因为1^1=0所有我们想到了或异法求解第一步先遍历0~1000的数然后用或异求和然后遍历数组同样或异求和

举个例子以**{1,3,4,2,5,3}数组为例(134253)(12345)=3**即3为重复的数字

  public static int getDuplicateNum(int[] arr){
        if (arr.length==0) return -1;
        int result=0;
        for (int i = 0; i <arr.length ; i++) {
            result ^=arr[i];
        }
        for (int i = 1; i <arr.length ; i++) {
            result ^=i;
        }
        return  result;
    }

测试代码:

public static void main(String[] args) {
    int[] arr=new int[1001];
    for (int i = 0; i <1000 ; i++) {
        arr[i]=i;
    }
    arr[1000]=6;
    int num = getDuplicateNum(arr);
    System.out.println("重复数字为:"+num);
    int num1 = getDuplicateNum2(new int[]{1,2,3,4,5,6,7,3});
    System.out.println("重复数字为:"+num1);
    int num2 = getDuplicateNum1(arr);
    System.out.println("重复数字为:"+num2);
}
Files\Java\jdk1.8.0_74\jre\lib\rt.jar;E:\workspace\JavaAlgorithmInterview\out\production\JavaAlgorithmInterview" 
重复数字为:6
重复数字为:3
重复数字为:6
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值