判断数组中是否存在重复数字

题目描述

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

我的解题思路:

       暴力穷举法,依次对比每个数,有重复就return。

边界条件:

       输入的数组为空

复杂度:

       时间复杂度:O(n2) 空间复杂度:O(1)

解决中遇到的问题:

       循环时,两个循环嵌套,第二个循环代表要和第一个循环中比较的数,由于我第二个循环也和第一个循环的起始值一样,所以一直判断是true,这里注意,这种方式第二个循环的初始值应该是i+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;

    public boolean duplicate(int numbers[],int length,int [] duplication) {
        if(length == 0 || duplication == null){
            return false;
        }      
        for(int i = 0 ;i < length;i++){
            //duplication[0] = numbers[i];不用复制,直接比较数组位置就好
            for(int j= i+1;j < length;j++){
                if(numbers[j] == numbers[i]){
                    duplication[0] = numbers[j];
                    return true;
                }
            }
            
        }
        //duplication[0] = -1;
        return false;
    }
}

优化思路:

1.排序后再比较

       数组中比较大小这种题应该考虑下是否能排序。先排序,如果有重复的,那么必存在相邻两个数相等的情况。这样就少了嵌套的循环。

       时间复杂度:        空间复杂度O(1)

注意要import对应的包,不然报错,找不到的。

import java.util.Arrays;
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;

    public boolean duplicate(int numbers[],int length,int [] duplication) {
        if(length == 0 || duplication == null){
            return false;
        }   
        Arrays.sort(numbers);
        for(int i = 0 ;i < length-1;i++){
            //duplication[0] = numbers[i];不用复制,直接比较数组位置就好
            if(numbers[i] == numbers[i+1]){
                duplication[0] = numbers[i];
                return true;
            }
            
            
        }
        //duplication[0] = -1;
        return false;
    }
}

2.利用hash表

     从头开始遍历,从hash表中找当前元素,如果存在则重复,不存在则把这个数加入hash表。

     时间复杂度O(n),用了Hash表,空间复杂度是O(n).

3.利用特性

          题目中的这句话很关键:

        因此,我们可以将数组元素的值和数组的下标联系起来。逐个判断,判断第i个数Q,看其取值时候为i,不是的话查找位置为Q的元素,看其值是否等于Q,不等于则交换二者的位置。再继续判断现在i位置上的数W是否等于位置w上的数,不等于则交换,等于则移到下一位继续判断。

       

完整代码:

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;
    public boolean duplicate(int numbers[],int length,int [] duplication) {
        if(length == 0 || duplication == null){
            return false;
        }   
        for(int i=0;i<length;i++){
            while(i != numbers[i]){
                int j = numbers[i];
                if(numbers[i] == numbers[j]){
                    duplication[0] = numbers[i];
                    return true;
                }
                int temp = numbers[j];
                numbers[j] = numbers[i];
                numbers[i] = temp;
            }
                    
        }
        return false;
    }
}

时间复杂度O(n),假设12300。最坏可以通过n次循环找到重复元素。因为前面的n-1次循环可以将n-1个数放在他们对应的位置上,相当于从小到大排序,后面的数比和前面对应位置的数相等。

 

相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页