每日一题318. 最大单词长度乘积
LeetCode题目:https://leetcode.cn/problems/maximum-product-of-word-lengths/
哈希表解法
直接构建二维数组,将每个字符串的哈希表存储进入二维数组,然后逐个进行对比。如果符合计算要求,则进行长度乘积计算,并存储最大值作为结果。
代码如下:
class Solution {
List<int[]> hashMap=new ArrayList<int[]>();
public int maxProduct(String[] words) {
int result = 0;
int isRepeat = 0;
for (int i = 1; i < words.length; i++) {
int[] hashTemp = new int[26];
for (int j = 0; j < words[i - 1].length(); j++) {
hashTemp[words[i - 1].charAt(j) - 'a']++;
}
hashMap.add(hashTemp);
result = Math.max(result, check(words, words[i]));
}
return result;
}
public int check(String[] words, String word) {
int x = 0;
int isRepeat = 0;
for (int i = 0; i < hashMap.size(); i++) {
for (int j = 0; j < word.length(); j++) {
if ( hashMap.get(i)[word.charAt(j) - 'a'] != 0) {
isRepeat = 1;
break;
}
}
if (isRepeat == 0) {
x = Math.max(words[i].length() * word.length(), x);
}
isRepeat = 0;
}
return x;
}
}
使用哈希表进行暴力解法有个问题,因为一共n个字符串,每个字符串之间都要进行,因此一共需要n!次对比。如果每次都使用int[26]的数组进行循环对比非常耗时。
因此,由于小写字母的索引是连续的,并且只有26个,因此可以使用位运算的方法来实现快速的对比索引。当两个位运算与操作为0,则说明没有重叠的数据。
所以将哈希操作替换为二进制位掩码操作,然后进行逐个校验。
代码如下:
class Solution {
public int maxProduct(String[] words) {
int length = words.length;
int[] masks = new int[length];
for (int i = 0; i < length; i++) {
String word = words[i];
int wordLength = word.length();
for (int j = 0; j < wordLength; j++) {
masks[i] |= 1 << (word.charAt(j) - 'a');
}
}
int maxProb = 0;
for (int i = 0; i < length; i++) {
for (int j = i + 1; j < length; j++) {
if ((masks[i] & masks[j]) == 0) {
maxProb = Math.max(maxProb, words[i].length() * words[j].length());
}
}
}
return maxProb;
}
}