[LeetCode] 存在重複元素

存在重複元素


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;
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章