剑指 Offer II 005. 单词长度的最大乘积](https://leetcode-cn.com/problems/aseY1I/)
难度中等34
给定一个字符串数组 words
,请计算当两个字符串 words[i]
和 words[j]
不包含相同字符时,它们长度的乘积的最大值。假设字符串中只包含英语的小写字母。如果没有不包含相同字符的一对字符串,返回 0。
示例 1:
输入: words = ["abcw","baz","foo","bar","fxyz","abcdef"]
输出: 16
解释: 这两个单词为 "abcw", "fxyz"。它们不包含相同字符,且长度的乘积最大。
示例 2:
输入: words = ["a","ab","abc","d","cd","bcd","abcd"]
输出: 4
解释: 这两个单词为 "ab", "cd"。
示例 3:
输入: words = ["a","aa","aaa","aaaa"]
输出: 0
解释: 不存在这样的两个单词。
提示:
2 <= words.length <= 1000
1 <= words[i].length <= 1000
words[i]
仅包含小写字母
解法 1:
class Solution {
public:
int maxProduct(vector<string>& words) {
for(int i(0); i < words.size(); i++)
{
sort(words[i].begin(), words[i].end());
}
int res(0);
for(int i(0); i < words.size(); i++)
{
for(int j(i + 1); j < words.size(); j++)
{
string r;
set_intersection(words[i].begin(), words[i].end(), words[j].begin(), words[j].end(), back_inserter(r));
int res_temp(words[i].size() * words[j].size());
if(r.empty() && res < res_temp)
{
res = res_temp;
}
}
}
return res;
}
};
解法 2:
class Solution {
public:
int maxProduct(vector<string>& words) {
vector<int> int_words(words.size(), 0);
for(int i(0); i < words.size(); i++)
{
for(int j(0); j < words[i].size(); j++)
{
int_words[i] |= (1 << (words[i][j] - 'a'));
}
}
int res(0);
for(int i(0); i < int_words.size(); i++)
{
for(int j(0); j < int_words.size(); j++)
{
if((int_words[i] & int_words[j]) == 0 && res < (words[i].size() * words[j].size()))
{
res = words[i].size() * words[j].size();
}
}
}
return res;
}
};
心得:
看到这道题首先想到的是最简单的方法,四层循环解决问题。但是显然四层循环是不可能的,所以进而又想到了使用集合进行一个交集,从而可以得到结果,这样得到解放时间复杂度是 O ( n 2 ) O(n^2) O(n2),但是在求交集这里花去的时间还是太多。最后,瞟了一眼题解后,发现可以用二进制代替集合,用与运算代替交集,从而可以大量节约求交集的时间,但时间复杂度 O ( n 2 ) O(n^2) O(n2)不会改变。