[LeetCode] Maximum Product of Word Lengths 單詞長度的最大積
Given a string array words
, find the maximum value of length(word[i]) * length(word[j])
where the two words do not share common letters. You may assume that each word will contain only lower case letters. If no such two words exist, return 0.
Example 1:
Given ["abcw", "baz", "foo", "bar", "xtfn", "abcdef"]
Return
16
The two words can be
"abcw", "xtfn"
.
Example 2:
Given ["a", "ab", "abc", "d", "cd", "bcd", "abcd"]
Return 4
The two words can be "ab", "cd"
.
Example 3:
Given ["a", "aa", "aaa", "aaaa"]
Return 0
No such pair of words.
這道題給我們了一個單詞陣列,讓我們求兩個沒有相同字母的單詞的長度之積的最大值。我開始想的方法是每兩個單詞先比較,如果沒有相同字母,則計算其長度之積,然後每次更新結果就能找到最大值。但是我開始想的兩個單詞比較的方法是利用雜湊表先將一個單詞的所有出現的字母存入雜湊表,然後檢查另一個單詞的各個字母是否在雜湊表出現過,若都沒出現過,則說明兩個單詞沒有相同字母,則計算兩個單詞長度之積並更新結果。但是這種判斷方法無法通過OJ的大資料集,上網搜大神們的解法,都是用了mask,因為題目中說都是小寫字母,那麼只有26位,一個整型數int有32位,我們可以用後26位來對應26個字母,若為1,說明該對應位置的字母出現過,那麼每個單詞的都可由一個int數字表示,兩個單詞沒有共同字母的條件是這兩個int數想與為0,用這個判斷方法可以通過OJ,參見程式碼如下:
解法一:
class Solution { public: int maxProduct(vector<string>& words) { int res = 0; vector<int> mask(words.size(), 0); for (int i = 0; i < words.size(); ++i) { for (char c : words[i]) { mask[i] |= 1 << (c - 'a'); } for (int j = 0; j < i; ++j) { if (!(mask[i] & mask[j])) { res = max(res, int(words[i].size() * words[j].size())); } } } return res; } };
還有一種寫法,藉助雜湊表,對映每個mask的值和其單詞的長度,每算出一個單詞的mask,遍歷雜湊表裡的值,如果和其中的mask值相與為0,則將當前單詞的長度和雜湊表中存的單詞長度相乘並更新結果,參見程式碼如下:
解法二:
class Solution { public: int maxProduct(vector<string>& words) { int res = 0; unordered_map<int, int> m; for (string word : words) { int mask = 0; for (char c : word) { mask |= 1 << (c - 'a'); } m[mask] = max(m[mask], int(word.size())); for (auto a : m) { if (!(mask & a.first)) { res = max(res, (int)word.size() * a.second); } } } return res; } };
參考資料: