存在重複元素
217、存在重複元素
難度:Easy
題目描述:
給定一個整數數組,判斷是否存在重複元素。
如果任意一值在數組中出現至少兩次,函數返回 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
解題思路:
解法一:暴力法
通過一個兩層循環,遍歷尋找重複元素。
有一個小小的改進,只需要在內層判斷某一元素後面的元素即可,不需要每次都遍歷全部的元素。
時間複雜度O(N^2),空間複雜度O(1)。
class Solution {
public:
bool containsDuplicate(vector<int>& nums) {
if (nums.size() == 1)
{
return false;
}
for (int i = 0; i < nums.size(); i++)
{
for (int j = 0; j < i; j++)
{
if (nums[i] == nums[j])
{
return true;
}
}
}
return false;
}
};
解法二:先排序
先對數組進行一次排序,然後對有序的數組進行一次遍歷,依次判斷相鄰元素是否相同。
排序算法的複雜度最優是O(nlgn),空間複雜度O(N)/O(1),取決於排序算法。
class Solution {
public:
bool containsDuplicate(vector<int>& nums) {
if (nums.size() <= 1)
{
return false;
}
sort(nums.begin(), nums.end()); // 先排序
for (int i = 0; i < nums.size() - 1; i++)
{
if (nums[i] == nums[i + 1])
{
return true;
}
}
return false;
}
};
解法三:哈希表
用哈希表記錄數組中的元素,如果有重複的可以O(1)時間內查詢到。
時間複雜度:O(N),空間複雜度O(N)。
- Your runtime beats 30.29 % of cpp submissions
- Your memory usage beats 5.72 % of cpp submissions (19.7 MB)
class Solution {
public:
bool containsDuplicate(vector<int>& nums) {
if (nums.size() <= 1)
{
return false;
}
unordered_map<int, int> res;
for (int i = 0; i < nums.size(); i++)
{
if (res.find(nums[i]) != res.end())
{
return true;
}
res.insert({nums[i], i});
}
return false;
}
};
219、存在重複元素-2
難度:Easy
題目描述:
給定一個整數數組和一個整數 k,判斷數組中是否存在兩個不同的索引 i 和 j,使得 nums [i] = nums [j],並且 i 和 j 的差的 絕對值 至多爲 k。
示例 1:
輸入: nums = [1,2,3,1], k = 3
輸出: true
示例 2:
輸入: nums = [1,0,1,1], k = 1
輸出: true
示例 3:
輸入: nums = [1,2,3,1,2,3], k = 2
輸出: false
解題思路:
解法一:暴力法
通過二層循環,額外添加一個判斷即可。
時間複雜度O(N^2),空間複雜度O(1)。
會超時。
class Solution {
public:
bool containsNearbyDuplicate(vector<int>& nums, int k) {
for (int i = 0; i < nums.size(); i++)
{
for (int j = 0; j < i; j++)
{
if ((i - j) <= k && (nums[i] == nums[j]))
{
return true;
}
}
}
return false;
}
};
解法二:哈希Map方法
新建一個哈希Map,以數組的元素爲key,下標爲value。
遍歷數組中的元素,如果map中存在,而且其value與數組的下標差小於k,則有重複的
否則插入新的數據。
- Your runtime beats 41.57 % of cpp submissions
- Your memory usage beats 5.55 % of cpp submissions (16 MB)
class Solution {
public:
bool containsNearbyDuplicate(vector<int>& nums, int k) {
if (nums.size() < 1)
{
return false;
}
unordered_map<int, int> map;
for (int i = 0; i < nums.size(); i++)
{
if (map.count(nums[i]) != NULL && i - map[nums[i]] <= k)
{
return true;
}
map[nums[i]] = i;
}
return false;
}
};
解法三:Set方法
維護一個有K個元素的Set,裏面不包含重複元素。
每次進行判斷Set集合中是否有當前元素,有的話返回True。
插入元素。
如果Set中的元素超過了K個,就刪除最前面的那個,始終維護Set中的大小爲K。
class Solution {
public:
bool containsNearbyDuplicate(vector<int>& nums, int k) {
unordered_set<int> st; // 設一個set爲窗口
for (int i = 0; i < nums.size(); ++i) {
if (!st.insert(nums[i]).second) return true; // 插入失敗說明重複 否則完成插入
if (st.size() == k + 1) st.erase(nums[i-k]); // 保證窗口長度<=k+1
}
return false;
}
};