这是我参与11月更文挑战的第18天,活动详情查看:2021最后一次更文挑战
最大单词长度乘积
该题出自力扣的318题——最大长度乘积(中等题),题解是消化于官方题解,也算是对于基础运算符有了一知半解
审题
给定一个字符串数组 words,找到 length(word[i]) * length(word[j]) 的最大值,并且这两个单词不含有公共字母。你可以认为每个单词只包含小写字母。如果不存在这样的两个单词,返回 0。
-
这道题不难理解,就是给一个数组,找出数组内长度之乘积最大的数,并且携带一个条件:两个字符串不能有相同的字符
-
(×)方法一:双指针
- 最初是真的有点冲昏头脑,妄想用双指针的方式去实现;
- 首尾指针,并且加个判断循环:两个字符之间是否存在相同字符
- 但是有个最大的败北就是,指针的移动,移动最小的最终结果却不一定正确
-
(√)方法二:暴力循环
- 暴力循环也不是不行,首先要双重for循环遍历数组
- 每两个字符串之间再比较是否有相同
- 光是上面都几重循环了,击败5%
-
(√)方法三:位运算
-
首先简单先了解位运算
- & :二进制位数都为1才为1,否则都为0
- | :二进制有一个位数为1即为1,否则为0
>>
右移位<<
左移位
-
循环数组,对数组内的字符串再次进行字符循环
- 字符 - ‘a’ 获取ASSIC值,并且用1右移来记录字母,再用 | 来存储字母存放的位置
- 再次循环,用 & 运算来计算是否有相同字符,没有则比较最大值
-
编码
public static int maxProduct(String[] words) {
int n = words.length;
int[] masks = new int[n];
for (int i = 0; i < n; i++) {
String word = words[i];
int wn = word.length();
for (int j = 0; j < wn; j++) {
int num = word.charAt(j) - 'a';
int a = 1 << num ;
masks[i] = masks[i] | a;
}
}
int maxProd = 0;
for (int i = 0; i < masks.length; i++) {
for (int j = i+1; j < masks.length; j++) {
if ((masks[i] & masks[j]) == 0){
maxProd = Math.max(maxProd,words[i].length() * words[j].length());
}
}
}
return maxProd;
}