Problem: 318. 最大单词长度乘积
思路
单词都是小写字母,想到暴力遍历每一种对比组合,大概是(n-1)!
次的对比,关键在于如何确定两个单词有无公共字母。
把他们变成charList再for循环比较?听着就累,因而想到用位运算来记录每个单词的特征,判断时将两单词的二进制位掩码相与就可以知道有无重复字母。
解题方法
- 预处理存储每个单词的位掩码
- 将字母的对应二进制位置为1
- 两层循环遍历掩码数组,将两个单词的位掩码相与
- 若相与后结果为0,说明没有重复的字母
- 每次结果都取数学最大值后返回
复杂度
-
时间复杂度:
O ( L + n 2 ) O(L+n^2) O(L+n2) L是单词列表中单词长度之和,预处理每个单词的位掩码需要遍历所有单词的所有字母,n^2是两层循环遍历掩码数组所花时间 -
空间复杂度:
O ( n ) O(n) O(n) n是数组words的长度,需要创建长度为n的掩码数组
Code
class Solution {
public int maxProduct(String[] words) {
int n = words.length;
int res = 0;
int masks[] = new int[n];//存储每个单词的二进制表示
for(int i = 0;i < n;i++){
String word = words[i];
int mask = 0;
for(char c: word.toCharArray()){
mask |= 1 << (c - 'a'); //将字母的对应二进制位置为1
}
masks[i] = mask;
}
for(int i = 0;i < n;i++){
String wordOne = words[i];
for(int j = i+1;j < n;j++){
String wordTwo = words[j];
if((masks[i] & masks[j]) == 0){ //判断两个单词的二进制位有无公共的1
res =Math.max(res ,wordOne.length() * wordTwo.length());
}
}
}
return res;
}
}