「LeetCode Top100」之雜湊篇

云雀AC了一整天發表於2024-08-04

1. 兩數之和

題目連結:https://leetcode.cn/problems/two-sum/description/?envType=study-plan-v2&envId=top-100-liked
解題狀態:透過
標籤:陣列雜湊表

思路:

透過建立一個雜湊表來儲存陣列中的元素,每當遍歷一個元素時,若雜湊表中不存在另一個與之相加為目標值的元素,就將元素插入到雜湊表中。

程式碼:

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        unordered_map<int, int> num;
        for(int i = 0; i < nums.size(); ++i) {
            auto iter = num.find(target - nums[i]);
            if(iter != num.end()) {
                return {iter->second, i};
            }
            num[nums[i]] = i;
        }
        return {};
    }
};

49. 字母異位詞分組

題目連結:https://leetcode.cn/problems/group-anagrams/description/?envType=study-plan-v2&envId=top-100-liked
解題狀態:個人思路無法實現,看題解透過!
標籤:陣列雜湊表字串排序

思路一:

使用unordered_map

由於異位詞中的字母是相同的且個數也是相同的,首先將字串中每個陣列內部排序,獲得唯一的排序,然後使用map來儲存當前唯一排序對應的字串,最後輸出map中的字串即可。

程式碼一:

class Solution {
public:
    vector<vector<string>> groupAnagrams(vector<string>& strs) {
        unordered_map<string, vector<string>> mp;
        for(string &str : strs) {
            string key = str;
            sort(key.begin(), key.end());
            mp[key].emplace_back(str);
        }
        vector<vector<string>> res;
        for(auto it = mp.begin(); it != mp.end(); ++it) {
            res.emplace_back(it->second);
        }
        return res;
    }
};

思路二:

使用雜湊表,官方題解中將字串中每個字母出現的次數使用字串表示,作為雜湊表的鍵。但是程式碼寫的真是一言難盡,根本不想看。

程式碼二:

class Solution {
public:
    vector<vector<string>> groupAnagrams(vector<string>& strs) {
        // 自定義對 array<int, 26> 型別的雜湊函式
        auto arrayHash = [fn = hash<int>{}] (const array<int, 26>& arr) -> size_t {
            return accumulate(arr.begin(), arr.end(), 0u, [&](size_t acc, int num) {
                return (acc << 1) ^ fn(num);
            });
        };

        unordered_map<array<int, 26>, vector<string>, decltype(arrayHash)> mp(0, arrayHash);
        for (string& str: strs) {
            array<int, 26> counts{};
            int length = str.length();
            for (int i = 0; i < length; ++i) {
                counts[str[i] - 'a'] ++;
            }
            mp[counts].emplace_back(str);
        }
        vector<vector<string>> ans;
        for (auto it = mp.begin(); it != mp.end(); ++it) {
            ans.emplace_back(it->second);
        }
        return ans;
    }
};

128. 最長連續序列

題目連結:https://leetcode.cn/problems/longest-consecutive-sequence/description/?envType=study-plan-v2&envId=top-100-liked
解題狀態:個人思路無法實現,看題解透過!
標籤:並查集陣列雜湊表

思路:

使用雜湊表來儲存序列中的所有元素,然後遍歷每個元素,先判斷當前元素的前一個數值是否存在這個雜湊表中,若不存在則表示當前元素是第一個連續元素,接著遍歷是否包含下一個數值,最後返回最長的連續序列。

程式碼:

class Solution {
public:
    int longestConsecutive(vector<int>& nums) {
        unordered_set<int> num_set;
        for(auto &num : nums) num_set.insert(num);
        int longStreak = 0;
        for(auto &num : num_set) {
            if(!num_set.count(num - 1)) {
                int currentNum = num;
                int currentStreak = 1;
                while(num_set.count(currentNum + 1)) {
                    currentNum += 1;
                    currentStreak += 1;
                }
                longStreak = max(longStreak, currentStreak);
            }
        }
        return longStreak;
    }
};

相關文章