leetcode-217-存在重复元素(Contains Duplicate)-java

题目及测试用例

package pid217;
/*存在重复

给定一个整数数组,判断是否存在重复元素。

如果任何值在数组中出现至少两次,函数返回 true。如果数组中每个元素都不相同,则返回 false。

示例 1:

输入: [1,2,3,1]
输出: true

示例 2:

输入: [1,2,3,4]
输出: false

示例 3:

输入: [1,1,1,3,3,4,3,2,4,2]
输出: true



*/


public class main {
    
    public static void main(String[] args) {
        int[][] testTable = {{1,2,3,1},{1,2,3,4},{1,1,1,3,3,4,3,2,4,2},{1,6,2,7,1}};
        for (int[] ito : testTable) {
            test(ito);
        }
    }
        
    private static void test(int[] ito) {
        Solution solution = new Solution();
        boolean rtn;
        long begin = System.currentTimeMillis();
        for (int i = 0; i < ito.length; i++) {
            System.out.print(ito[i]+" ");            
        }
        System.out.println();
        //开始时打印数组
        
        rtn = solution.containsDuplicate(ito);//执行程序
        long end = System.currentTimeMillis();    
        
        //System.out.println(ito + ": rtn=" + rtn);
        System.out.println(ito + ": rtn=" +rtn);
//        for (int i = 0; i < ito.length; i++) {
//            System.out.print(ito[i]+" ");
//        }//打印结果几数组
        
        System.out.println();
        System.out.println("耗时:" + (end - begin) + "ms");
        System.out.println("-------------------");
    }

}

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62

解法1(部分成功,最后一个超时)
超级缓慢的解法,一个一个查是否重复

package pid217;

public class Solution {
public boolean containsDuplicate(int[] nums) {
    int length=nums.length;
    if(length==0||length==1)
        return false;
    
    for(int i=1;i<length;i++){
        int now=nums[i];
        for(int j=0;j<i;j++){
            if(now==nums[j]){
                return true;
            }
        }
    }    
    return false;
    }

}

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21

解法2(部分成功,最后一个超时,采用快排的思想,找到则返回)
查看最后一个测试用例,有27万个数字

class Solution {
   public static boolean isDuplicate=false;
    public boolean containsDuplicate(int[] nums) {
        isDuplicate=false;
        int length=nums.length;
        if(length==0||length==1)
            return false;
        fastSortDuplicate(nums,0,length-1);
    return isDuplicate;
    }
    
    
    
    
    
    private void fastSortDuplicate(int[] nums,int begin,int last) {
        if(isDuplicate==true){
            return;
        }
        int length=nums.length;
        if(length==0||length==1){
            return;
        }
        
        int base=nums[begin];
        int i=begin;
        int j=last;
        int mid=0;
        //i为第一个,j为最后一个,base为第一个数字,此时i处为base
        while(true){
            //j从后往前找到比base小的数字,与i作颠倒,颠倒后j处为base,i处为之前j处比base小的数
            while(j!=i){
                if(nums[j]<base ){
                    nums[i]=nums[j];
                    nums[j]=base;
                    break;
                }
                else{
                    if(nums[j]==base ){
                        if(i==j){
                            mid=i;
                            break;
                        }
                        System.out.println(base);
                        System.out.println(j);
                        isDuplicate=true;
                        return;
                    }
                    else{
                        j--;
                    }
                    
                }
            }
            //如果上一个j过程结束,如果i与j相同,中间为i,跳出大过程
            if(i==j){
                mid=i;
                break;
            }
            //i从后往前找到比base大的数字,与j作颠倒,颠倒后i处为base,j处为之前i处比base大的数,跳出这个小循环
            i++;
            while(i!=j){
                if(nums[i]>base){
                    nums[j]=nums[i];
                    nums[i]=base;
                    break;
                }
                else{
                    if(nums[i]==base ){
                        if(i==j){
                            mid=i;
                            break;
                        }
                        System.out.println(base);
                        System.out.println(i);
                        isDuplicate=true;
                        return;
                    }
                    else{
                        i++;
                    }
                }
            }
            //如果上一个i过程结束,如果i与j相同,中间为i,跳出大过程
            if(i==j){
                mid=i;
                break;
            }
            
        }
        //System.out.println(Arrays.toString(nums));
        //从此处开始mid处为base,比mid处大的,则比base大,反之亦然
        //对两次进行递归快速排序
        if((mid-begin)>1){
            fastSortDuplicate(nums, begin, mid-1);
        }
        if((last-mid)>1){
            fastSortDuplicate(nums, mid+1, last);            
        }        
        
        return;
        
        
    }
}

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105

解法3(成功,24ms,比较快)
采用set的数据结构

    public boolean containsDuplicate(int[] nums) {
        int length=nums.length;
        HashSet<Integer> set=new HashSet<>();
        for(int i=0;i<length;i++){
            if(set.contains(nums[i])){
                return true;
            }
            set.add(nums[i]);
        }
        
        return false;
    }

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

解法4(别人的,8ms很快)
使用计数排序的思想,创建一个新数组来计数
这个方法按道理,时间复杂度和set是一样的,还要遍历两次,但是之所以快,可能是hashset内部操作虽然是O(1),但是有几部操作,反而比计数排序每位总共只做三个操作慢



public boolean containsDuplicate(int[] nums) {
        if (nums.length == 0) {
            return false;
        }
        int min = nums[0];
       int max = nums[0];
        for (int i = 0; i < nums.length; i++) {
            max = Math.max(max,nums[i]);
            min = Math.min(min,nums[i]);
        }
        int d = max - min;
        int[] arr = new int[d + 1];
        for (int i = 0; i < nums.length; i++) {
            arr[nums[i] - min]++;
            if (arr[nums[i] - min] == 2) {
                return true;
            }
        }
        return false;
    }



---------------------
作者:xushiyu1996818
来源:CSDN
原文:https://blog.csdn.net/xushiyu1996818/article/details/81317572
版权声明:本文为博主原创文章,转载请附上博文链接!

posted @ 2019-07-06 18:14  天涯海角路  阅读(247)  评论(0)    收藏  举报