【剑指offer】面试3.1数组中重复的数字(java版)

题目描述:

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

public class FindDuplicate {
    //方法1:排序O(nlogn)
    public static boolean duplicate(int []numbers){
        for (int i = 0; i < numbers.length; i++) {
            if(numbers[i]<0||numbers[i]>numbers.length-1){
                System.out.println("无效的测试用例");
                return false;
            }
        }
        Arrays.sort(numbers);
        int result=0;
        for (int i = 0; i < numbers.length-1; i++) {
            if(numbers[i]==numbers[i+1]){//如果是重复元素,位置是相邻的;
                 result=numbers[i];
                System.out.println("第一个重复的元素"+result);
                 return true;
            }
        }
        return false;
    }
    //方法2:使用哈希表时间复杂度O(n),空间复杂度是O(n);
    public static boolean duplicate2(int []numbers){
        if (numbers == null || numbers.length == 0){
            return false;
        }
        for (int i = 0; i < numbers.length; i++) {
            if(numbers[i]<0||numbers[i]>numbers.length-1){
                System.out.println("无效的测试用例");
                return false;
            }
        }
        Map<Integer,Integer> map=new HashMap<>();
        int result=0;
        for (int i = 0; i < numbers.length; i++) {
            if(!map.containsValue(numbers[i])){//map中<i,numbers[i]>,如果map中不包含numbers[i]就添加
                map.put(i,numbers[i]);
            }else {
                result=numbers[i];//map中包含,就是重复元素
                System.out.println("重复元素为"+result);
                return true;
            }
        }
        return false;
    }
    //使用推荐做法,时间复杂度O(n)
    /*情况1:numbers[i]==i,扫描下一个数字
    * 情况2:numbers[i]!=i,eg:(numbers[4]=2)!=下标4
    *        then:numbers[i]和number[number[i]]比较,
    *             如果相等,就有重复元素eg:numbers[4]=2,我们们要比较2这个位置上的元素是不是等于2
    *             如果不相等:就交换 让numbers[i]回到下标和它相等的位置eg:numbers[0]=2,那么就让它和下标为2的元素交换
    * */
    //结果[0,1,2,3]//数值和下标是相等的
public static boolean duplicate3(int []numbers){
    if(numbers==null||numbers.length==0){
        return false;
    }
    for (int i = 0; i < numbers.length; i++) {
        if(numbers[i]<0||numbers[i]>numbers.length-1){
            System.out.println("无效的测试用例");
            return false;
        }
    }

    for (int i = 0; i < numbers.length; i++) {
        int result=0;
        while (numbers[i]!=i){  //我和我的下标不相等,我就要回到和我下标相等的位置
          if(numbers[i]==numbers[numbers[i]]){//发现下标里面放的是和我一样的值,那么我就直接返回true
              result=numbers[i];
              System.out.println("重复的元素"+result);
              return true;
          }
          int temp=numbers[i];//发现和我的值不一样,就要调换
          numbers[i]=numbers[numbers[i]];
          numbers[numbers[i]]=temp;
        }
    }
    return false;
}
    public static void main(String[] args) {
    //包含一个或者多个的重复元素的数字
        int[]numbers={2,3,1,0,2,5,3};
        System.out.println(duplicate(numbers));
        System.out.println(duplicate2(numbers));
        System.out.println(duplicate3(numbers));
        //数组中不包含重复数字
        System.out.println("=========================");
        int[]numbers2={2,3,1,0,4,5};
        System.out.println(duplicate(numbers2));
        System.out.println(duplicate2(numbers2));
        System.out.println(duplicate3(numbers2));
        //无效的测试用例
        System.out.println("=========================");
        int[]numbers3={-2,3,1,0,4,5,7};
        System.out.println(duplicate(numbers3));
        System.out.println(duplicate2(numbers3));
        System.out.println(duplicate3(numbers3));
    }
}

第一个重复的元素2
true
重复元素为2
true
重复的元素2
true
=========================
false
false
false
=========================
无效的测试用例
false
无效的测试用例
false
无效的测试用例
false



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值