LeetCode——318. 最大单词长度乘积[Maximum Product of Word Lengths][中等]——分析及代码[C++]
一、题目
给定一个字符串数组 words,找到 length(word[i]) * length(word[j]) 的最大值,并且这两个单词不含有公共字母。你可以认为每个单词只包含小写字母。如果不存在这样的两个单词,返回 0。
示例 1:
输入: ["abcw","baz","foo","bar","xtfn","abcdef"]
输出: 16
解释: 这两个单词为 "abcw", "xtfn"。
示例 2:
输入: ["a","ab","abc","d","cd","bcd","abcd"]
输出: 4
解释: 这两个单词为 "ab", "cd"。
示例 3:
输入: ["a","aa","aaa","aaaa"]
输出: 0
解释: 不存在这样的两个单词。
提示:
- 2 <= words.length <= 1000
- 1 <= words[i].length <= 1000
- words[i] 仅包含小写字母
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/maximum-product-of-word-lengths
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
二、分析及代码
1. 位运算
(1)思路
根据题意,先记录每种字母组合所构成单词的最大长度,然后遍历任意 2 种组合,输出无公共字母时的最大单词乘积即可。
因为 words[i] 仅包含小写字母,可用一个整数 26 位二进制的 0 和 1,表示对应的字母组合。
(2)代码
class Solution {
public:
int maxProduct(vector<string>& words) {
unordered_map<int, int> len;//哈希表,key为单词包含字母的二进制表示,val为这些字母组成单词的最大长度
for (string word : words) {
int mask = 0, size = word.size();//二进制表示,单词长度
for (int i = 0; i < size; i++) {
mask |= 1 << (word[i] - 'a');//将单词包含的字母转换为二进制表示
}
if (len.count(mask) == 0 || len[mask] < size) {//更新哈希表
len[mask] = size;
}
}
int ans = 0;
for (auto [mask1, _] : len) {//遍历第一个单词
for (auto [mask2, _] : len) {//遍历第二个单词
if ((mask1 & mask2) == 0) {//与运算结果为0,对应2个单词无公共字母
ans = max(ans, len[mask1] * len[mask2]);//更新最大单词长度乘积
}
}
}
return ans;
}
};
(3)结果
执行用时 :48 ms,在所有 C++ 提交中击败了 43.10% 的用户;
内存消耗 :16.7 MB,在所有 C++ 提交中击败了 22.50% 的用户。
三、其他
暂无。