数组中的重复数字

数组中的重复数字

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

思想
1.利用本题的性质,由于所有数字都在0-n-1,因此,如果没有重复则所有数字都顺序排列应该为0-n-1。当数字与数组下标相等时,则进入下次循环,如果不相等则循环知道相等,在循环中判断如果数字和他对应位置值相等则返回真即为有重复值,否则交换位置把数字换到他应有的位置。遍历结束返回false。时间复杂度O(n),空间复杂度O(1)。
(注:在交换时,注意交换的下标。)

public boolean duplicate(int numbers[],int length,int [] duplication) {
        if (numbers == null || length < 1)
            return false;
        int dupLen = 0;
        int temp;
        for (int i = 0; i < length; i++) {
            while (numbers[i] != i) {
                if (numbers[i] == numbers[numbers[i]]) {
                    duplication[dupLen++] = numbers[i];
                    return true;
                }
                //这里在写的时候没有注意到numbers[i]与temp相等的问题,导致出现死循环
                temp = numbers[i];
                numbers[i] = numbers[temp];
                numbers[temp] = temp;
            }
        }
        return false;
    }

2.先对数组进行排序,然后遍历判断前后是否有重复。时间复杂度O(nlog(n))。
(注:在测试时,不只有返回结果会进行测试,重复数字也在测试范围内。)

public static boolean duplicateSort(int numbers[], int length, int[] duplication) {
        if (numbers == null || length == 0) return false;
        quickSort(numbers, 0, length-1);
        int dupLen = 0;
        for (int i = 0; i < length-1; i++) {
            if (numbers[i] == numbers[i+1]) {
                duplication[dupLen++] = numbers[i];
                return true;
            }
        }
        return false;
    }
    //快速排序
    public static void quickSort(int numbers[], int low,int high){
        if (low < high){
            int p = partition(numbers, low, high);
            quickSort(numbers, low, p-1);
            quickSort(numbers, p+1, high);
        }
    }
    //快速排序划分算法,返回位置
    public static int partition(int numbers[],int low,int high){
        int p = numbers[low];
        while(low<high){
            while(low < high && numbers[high] >= p) high--;
            numbers[low] = numbers[high];
            //注意,这里low是低位,指针要向上修改,自增
            while (low < high && numbers[low] <= p) low++;
            numbers[high] = numbers[low];
        }
        numbers[low] = p;
        return low;
    }

3.使用HashSet,进行一次遍历,如果数组元素存在,则重复,如果不存在,将其加入到HashSet中。时间复杂度是O(n),缺点是利用了空间为n的hashset。
(注:用HashSet需要导包。)

public static boolean duplicateHash(int numbers[], int length, int[] duplication) {
        if (numbers == null || length == 0) return false;
        HashSet<Integer> hashSet = new HashSet<Integer>();
        int depLen = 0;
        for (int i = 0; i < length; i++) {
            if (hashSet.contains(numbers[i])) {
                duplication[depLen++] = numbers[i];
                return true;
            } else {
                hashSet.add(numbers[i]);
            }
        }
        return false;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值