005 Leetcode 318 单词最大长度的乘积
给定一个字符串数组 words,请计算当两个字符串 words[i] 和 words[j] 不包含相同字符时,它们长度的乘积的最大值。假设字符串中只包含英语的小写字母。如果没有不包含相同字符的一对字符串,返回 0。
示例 1:
输入: words = ["abcw","baz","foo","bar","fxyz","abcdef"] 输出: 16 解释: 这两个单词为 "abcw", "fxyz"。它们不包含相同字符,且长度的乘积最大。
来源:力扣(LeetCode) 链接:力扣
题解:位运算
1.用二进制掩码表示单词word
2.比较二进制掩码,若为0则无相同字符 word[i]&word[j]=0
3.遍历求得乘积的最大值
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 = words[i].length(); for(int j=0;j<wordLength;j++){ masks[i] |= 1<<(word.charAt(j)-'a'); } } int maxPod = 0; for(int i=0;i<length;i++){ for(int j=i+1;j<length;j++){ if((masks[i]&masks[j])==0){ maxPod = Math.max(maxPod, words[i].length()*words[j].length()); } } } return maxPod; } }
位运算优化
位掩码+哈希
'meet'和'met'有重复字符,长度不同,用哈希表只保存最长的单词。然后将去重过的单词们的长度进行乘积比较。
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 maxpod = 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); maxpod = Math.max(maxpod, wordLength1*wordLength2); } } } return maxpod; } }