Every day a leetcode
题目来源:219. 存在重复元素 II
解法1:暴力
代码:
class Solution
{
public:
bool containsNearbyDuplicate(vector<int> &nums, int k)
{
int n = nums.size();
if (n < 2)
return false;
for (int i = 0; i < n; i++)
{
for (int j = i + 1; j < min(n, i + k + 1); j++)
{
if (nums[i] == nums[j])
return true;
}
}
return false;
}
};
结果:
复杂度分析:
时间复杂度:O(n*k)
空间复杂度:O(1)
解法2:哈希
我们使用STL unordered_map作为哈希表。
代码:
class Solution
{
public:
bool containsNearbyDuplicate(vector<int> &nums, int k)
{
int n = nums.size();
if (n < 2)
return false;
unordered_map<int, int> umap;
for (int i = 0; i < n; i++)
{
if (umap.find(nums[i]) != umap.end() && i - umap[nums[i]] <= k)
return true;
umap[nums[i]] = i;
}
return false;
}
};
结果:
复杂度分析:
时间复杂度:O(n),其中n是数组nums的长度。需要遍历数组一次,对于每个元素哈希表的操作时间都是 O(1)。
空间复杂度:O(n),其中n是数组nums的长度。需要使用哈希表记录每个元素的最大下标,哈希表中的元素个数不会超过 n。
解法3:滑动窗口
代码:
/*
* @lc app=leetcode.cn id=219 lang=cpp
*
* [219] 存在重复元素 II
*/
// @lc code=start
// class Solution
// {
// public:
// bool containsNearbyDuplicate(vector<int> &nums, int k)
// {
// int n = nums.size();
// if (n < 2)
// return false;
// unordered_map<int, int> umap;
// for (int i = 0; i < n; i++)
// {
// if (umap.find(nums[i]) != umap.end() && i - umap[nums[i]] <= k)
// return true;
// umap[nums[i]] = i;
// }
// return false;
// }
// };
class Solution
{
public:
bool containsNearbyDuplicate(vector<int> &nums, int k)
{
int n = nums.size();
if (n < 2)
return false;
unordered_set<int> uset;
for (int i = 0; i < n; i++)
{
if (i > k)
uset.erase(nums[i - k - 1]);
if (uset.find(nums[i]) != uset.end())
return true;
uset.insert(nums[i]);
}
return false;
}
};
// @lc code=end
结果:
复杂度分析:
时间复杂度:O(n)。其中 n 是数组 nums 的长度。需要遍历数组一次,对于每个元素,哈希集合的操作时间都是 O(1)。
空间复杂度:O(k),其中 k 是判断重复元素时允许的下标差的绝对值的最大值。需要使用哈希集合存储滑动窗口中的元素,任意时刻滑动窗口中的元素个数最多为 k+1 个。