题目链接
https://leetcode-cn.com/problems/maximum-product-of-word-lengths
题目
给定一个字符串数组 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]
仅包含小写字母
思路一
暴力法,直接两个for循环,枚举所有可能。
C++ Code
class Solution {
public:
bool HasPublic(string s1,string s2){
unordered_set<int> hashset;
for(char ch:s1)
{
hashset.insert(ch);
}
for(char ch:s2)
{
if(hashset.count(ch) > 0) return true;
}
return false;
}
int maxProduct(vector<string>& words) {
int MaxVal=0;
for(int i=0;i<words.size()-1;i++)
{
for(int j=i+1;j<words.size();j++)
{
if(HasPublic(words[i],words[j])==false)
{
MaxVal=max(MaxVal,int(words[i].size()*words[j].size()));
}
}
}
return MaxVal;
}
};
结果
很不幸,暴力超时。
思路二
因为只有26位小写字母,所以可以把每一个word转成int存放,哪个字母出现就让他在对应的二进制位置为1,然后将两个数组对应位相&,仅当1&1=1,即当字母在两个字符串中均出现时为1.
C++ Code
class Solution {
public:
int maxProduct(vector<string>& words) {
int MaxVal=0;
for(int i=0;i<words.size()-1;i++)
{
vector<int> N1(26,0);
for(char ch:words[i])
{
N1[ch-'a']=1;
}
for(int j=i+1;j<words.size();j++)
{
int result=0;
vector<int> N2(26,0);
for(char ch:words[j])
{
N2[ch-'a']=1;
}
for(int k=0;k<26;k++)
{
result+=N1[k]&N2[k];
}
if(result==0)
{
MaxVal=max(MaxVal,int(words[i].size()*words[j].size()));
}
}
}
return MaxVal;
}
};
补充
本题还能进一步优化,即在程序最开始就把word里所有字符串都编码成长度为26位的二进制数组,这样就不需要重复编码了。