【面试算法专栏及回答思考】——存在重复元素

160 阅读2分钟

这是我参与11月更文挑战的第13天,活动详情查看:2021最后一次更文挑战

存在重复元素

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

如果存在一值在数组中出现至少两次,函数返回 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

解题

解题思路

题目要求判断一个整数数组是否存在重复元素。所以我们先在此做个假设,这个整数数组是一个已排序的数组,这样我们只需要比较数组相邻元素是否相等,相等就代表这个数组存在重复元素,否则不存在。这样来看是不是简单了许多?

这里给出两种解决方法:

方法一:考虑 HashSet 的性质,在 HashSet 中元素不允许重复,使用哈希表就可以进行判断 方法二:排序后进行比较,比较前后两个元素是否相等即可。

需要注意的是,本题给出的方法一也就是使用哈希表的方法,可以算作是使用哈希表检查重复元素的一个模板,需要掌握。

解题过程

解法一:哈希表

维护一个哈希表 set,在 set 中查找是否存在数组中的元素,如果能查找到,则代表数组存在重复元素,否则将该元素加入到 set 中,继续查找。

class Solution {
    public boolean containsDuplicate(int[] nums) {
       Set<Integer> set = new HashSet<>();
       for(int num : nums){
           if(!set.add(num)){
               return true;
           }
       }
       return false;
    }
}

解法二:排序

第二种方法就是利用排序+判断相邻元素查找是否重复。考虑到速度问题,采用快排,对序列进行排序后,重复元素一定会出现在相邻位置上。时间复杂度O(NlogN),空间复杂度O(logN),需要考虑递归调用栈的深度。

int cmp(const void *a, const void *b) {
    return *(int *)a - *(int *)b;
}

bool containsDuplicate(int* nums, int numsSize){
    /* 特判 */
    if (nums == NULL || numsSize <= 0) {
        return false;
    }

    /* 排序 */
    qsort(nums, numsSize, sizeof(int), cmp);
    /* 遍历整个数组,查找相邻元素是否相等 */
    for (int i = 0; i < numsSize - 1; ++i) {
        /* 如果不相等,i 递增,继续查找,直到遍历整个数组 */
        if (nums[i] != nums[i + 1]) {
           continue;
        }
        return true;
    }
    return false;
}

除以上方法,同学们也可以试试用集合来实现,或者也有不少其他方法可以尝试。欢迎留言讨论,共同进步。