思考:
(1)哈希表暴力求解
(2)位运算求解
(1)哈希表暴力求解比较简单,大的思路是将每一个字符串和其他字符串进行比较,如果有相同字母就pass,否则就将两个字符串的大小相乘,求最大。在具体比较字符串的操作中,使用哈希表,将第一个字符串的数据放进哈希表,用遍历第二个字符串的所有字符,有在哈希表里查到就返回,不再考虑。
可以看到随着数据的上升,所消耗的时间复杂度和空间复杂度非常的高,因为本质上是对所有数据也就是所有字符进行了遍历,属于是暴力算法。
class Solution {
public:
int maxProduct(vector<string>& words) {
unordered_map<int, int> freq;
bool flag=false;
int res=0;
for (int i = 0;i < words.size();i++)
{
freq.clear();
for (int num:words[i])
{
++freq[num];
}
for (int j = i + 1;j < words.size();j++)
{
for (int k = 0;k < words[j].size();k++)
{
char ch = words[j][k];
int it = freq.count(ch);
if (it != 0)
{
flag = true;
break;
}
}
if (flag == false)
{
int thiss = words[i].size() * words[j].size();
res = max(res, thiss);
}
flag = false;
}
}
return res;
}
};
(2)位运算求解的思路是,因为只有26个字母,可以通过将一个字符串转换成2进制,然后通过二进制的位运算来判断是否有重复的字母,如果用与运算来比较2个字符串的二进制,如果为0则代表没有一位是重复的,也就是没有重复的字母,否则一定有地方是相同的,这样就能判断是否有重复字母了。
我们可以看到第一个二重 for循环就是在将字符串转换为二进制,第二个二重for循环就是传统的遍历所有的字符串对,判断是否有重合字母。
class Solution {
public:
int maxProduct(vector<string>& words) {
int length = words.size();
vector<int> masks(length);
for (int i = 0; i < length; i++) {
string word = words[i];
int wordLength = word.size();
for (int j = 0; j < wordLength; j++) {
masks[i] |= 1 << (word[j] - 'a');
}
}
int maxProd = 0;
for (int i = 0; i < length; i++) {
for (int j = i + 1; j < length; j++) {
if ((masks[i] & masks[j]) == 0) {
maxProd = max(maxProd, int(words[i].size() * words[j].size()));
}
}
}
return maxProd;
}
};