剑指offer专项突破系列005

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;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值