1. 程式人生 > >[LeetCode] Map Sum Pairs 映射配對之和

[LeetCode] Map Sum Pairs 映射配對之和

二分 prefix ref second www 位置 and leet www.

Implement a MapSum class with insert, and sum methods.

For the method insert, you‘ll be given a pair of (string, integer). The string represents the key and the integer represents the value. If the key already existed, then the original key-value pair will be overridden to the new one.

For the method sum

, you‘ll be given a string representing the prefix, and you need to return the sum of all the pairs‘ value whose key starts with the prefix.

Example 1:

Input: insert("apple", 3), Output: Null
Input: sum("ap"), Output: 3
Input: insert("app", 2), Output: Null
Input: sum("ap"), Output: 5

這道題讓我們實現一個MapSum類,裏面有兩個方法,insert和sum,其中inser就是插入一個鍵值對,而sum方法比較特別,是在找一個前綴,需要將所有有此前綴的單詞的值累加起來返回。看到這種玩前綴的題,照理來說是要用前綴樹來做的。但是博主一般想偷懶,不想新寫一個結構或類,於是就使用map來代替前綴樹啦。博主開始想到的方法是建立前綴和一個pair之間的映射,這裏的pair的第一個值表示該詞的值,第二個值表示將該詞作為前綴的所有詞的累加值,那麽我們的sum函數就異常的簡單了,直接將pair中的兩個值相加即可。關鍵就是要在insert中把數據結構建好,構建的方法也不難,首先我們suppose原本這個key是有值的,我們更新的時候只需要加上它的差值即可,就算key不存在默認就是0,算差值也沒問題。然後我們將first值更新為val,然後就是遍歷其所有的前綴了,給每個前綴的second都加上diff即可,參見代碼如下:

解法一:

class MapSum {
public:
    /** Initialize your data structure here. */
    MapSum() {}
    
    void insert(string key, int val) {
        int diff = val - m[key].first, n = key.size();
        m[key].first = val;
        for (int i = n - 1; i > 0; --i) {
            m[key.substr(
0, i)].second += diff; } } int sum(string prefix) { return m[prefix].first + m[prefix].second; } private: unordered_map<string, pair<int, int>> m; };

下面這種方法是論壇上投票最高的方法,感覺很叼,用的是帶排序的map,insert就是把單詞加入map。在map裏會按照字母順序自動排序,然後在sum函數裏,我們根據prefix來用二分查找快速定位到第一個不小於prefix的位置,然後向後遍歷,向後遍歷的都是以prefix為前綴的單詞,如果我們發現某個單詞不是以prefix為前綴了,直接break;否則就累加其val值,參見代碼如下:

解法二:

class MapSum {
public:
    /** Initialize your data structure here. */
    MapSum() {}
    
    void insert(string key, int val) {
        m[key] = val;
    }
    
    int sum(string prefix) {
        int res = 0, n = prefix.size();
        for (auto it = m.lower_bound(prefix); it != m.end(); ++it) {
            if (it->first.substr(0, n) != prefix) break;
            res += it->second;
        }
        return res;
    }
    
private:
    map<string, int> m;
};

參考資料:

https://discuss.leetcode.com/topic/103924/java-map-solution

https://discuss.leetcode.com/topic/104006/c-easy-solution-ordered-map

LeetCode All in One 題目講解匯總(持續更新中...)

[LeetCode] Map Sum Pairs 映射配對之和