![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/da070f7924584fc79ce2ff24540306b5.png)
位运算
解题思路:时间复杂度O(
L
∗
n
2
L * n^2
L∗n2),L是words中所有单词长度之和,n是单词个数。空间复杂度O(
n
n
n) |
---|
- 首先我们要找到两个不相交的单词(两个单词里面没有相同的字母)
- 然后对其长度相乘。如果有多个不相交单词,保存长度相乘最大的结果
- 如何判断两个单词是否不想交呢?
- 我们可以用一个二进制串,来记录当前单词出现哪些字母. 我们规定0代表a,1代表b,…,25代表z
- 例如单词apple,对应二进制为0000 0000 0000 0000 1000 1000 0001 0001.每个二进制代表0000 00zy xwvu tsrq ponm lkgi hgfe dcba
- 有了二进制串,我们将两个单词的二进制串相与,如果结果为0,就说明两个单词没有相同的字母
代码:官方增加了测试用例,目前最快是16ms,这里优化了一些步骤,达到了8ms。但是依然无法超过2022年时候测试用例少的时候提交的效率。 |
---|
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/7cdd73684e6640a8b928718fd21870fd.png)
class Solution {
public int maxProduct(String[] words) {
int n = words.length;
int[] temp = new int[n];
for(int i = 0; i < n; i++){
int binary = 0;
for(int j = 0; j < words[i].length(); j++){
int num = words[i].charAt(j) - 'a';
binary |= (1 << num);
}
temp[i] = binary;
}
int result = 0;
for(int i = 0; i < n; i++){
for(int j = 0; j < i; j++){
if((temp[i] & temp[j]) == 0){
result = Math.max(result,words[i].length() * words[j].length());
}
}
}
return result;
}
}
优化思路
法一中,如果有由相同字母组成的单词,生成的二进制串其实是一样的。例如meet和met。我们只需要除了meet就可以,因为meet更长。代码逻辑和上面是一样的,只不过需要优化这一点。但是因为用到HashMap集合,做题的效率比不过上面。
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/2b1c0f9b76fc45bd90cd79365ab6c764.png)
class Solution {
public int maxProduct(String[] words) {
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
int length = words.length;
for (int i = 0; i < length; i++) {
int mask = 0;
String word = words[i];
int wordLength = word.length();
for (int j = 0; j < wordLength; j++) {
mask |= 1 << (word.charAt(j) - 'a');
}
if (wordLength > map.getOrDefault(mask, 0)) {
map.put(mask, wordLength);
}
}
int maxProd = 0;
Set<Integer> maskSet = map.keySet();
for (int mask1 : maskSet) {
int wordLength1 = map.get(mask1);
for (int mask2 : maskSet) {
if ((mask1 & mask2) == 0) {
int wordLength2 = map.get(mask2);
maxProd = Math.max(maxProd, wordLength1 * wordLength2);
}
}
}
return maxProd;
}
}