题目大意
判断给定数组是否存在重复的元素。
解题思路
题意非常直观,而且题目本身也是 Easy 的级别。不过如何尽可能地减小算法的复杂度呢?
显然算法的复杂度不可能低于 O(n),因为你在遍历所有元素之前永远也不能下“不存在重复元素”的结论。
解决这个问题的一个经典的 O(n) 算法是统计排序,统计排序是一种非基于比较的排序算法,它通过建立一个数组 int cnt[]
来统计待排序数组中数出现的次数, cnt[index]
表示下标 index
在待排序数组中出现的次数,这样只要将待排序数组遍历一遍就可以确定有序的序列了。
利用相同的思路,创建一个布尔数组 bool dup[] = { false };
,对于给定数组中的每一个元素 n
,判断 dup[n]
是否为 true
,如果是,则说明 n
重复出现;否则将 dup[n]
标记为 true
。
完整代码
class Solution {
public:
bool containsDuplicate(vector<int>& nums) {
bool buckets[1000000] = { false };
for (int i = 0; i < nums.size(); i++) {
if (buckets[nums[i]]) return true;
else buckets[nums[i]] = true;
}
return false;
}
};
思考
虽然统计排序的时间效率很高,但很容易发现,它的空间开销是巨大的;如果这一题给出数组的最大值为 231 - 1,或者甚至是 long long
类型的数组,那么这种方法是开销巨大且不容易实现的,因而还有必要考虑更加普遍的方法。
目前的思路有两种:第一种是用常见的基于比较的排序算法先对数组进行排序;第二种则是使用哈希的方法将稀疏的数组映射到一个空间消耗可以接受的邻接表中。