力扣每日一题2021-11-17最大单词长度乘积


318.最大单词长度乘积

题目描述

最大单词长度乘积


思路

位运算

为得到最大单词长度乘积,朴素的做法是,遍历字符串数组words中的每一对单词,判断这一对单词是否有公共字母,如果没有公共字母,则用这一对单词的长度乘积更新最大单词长度乘积。
所以很直观的想到用集合去判断单词之间的交集,然后用哈希表存储之前的一些集合的最长长度,在这些长度里找当前集合不存在交集的最大乘积。但是因为set是不能哈希的,不能作为哈希表的key,所以可以用26位位运算表示26个字母被使用的情况。

Python实现

Python实现

class Solution:
    def maxProduct(self, words: List[str]) -> int:
        def hashset(word):
            # 用26位位运算表示26个字母在word中被使用的情况
            return sum(1 << (ord(c) - ord('a')) for c in set(word))
        
        d, ans = defaultdict(int), 0
        for word in words:
            h = hashset(word)
            if d[h] < len(word):
                for other in d:
                    # 如果位运算&的结果为0,说明没有同样的字母,可以计算乘积
                    if not other & h:
                        ans = max(ans, len(word) * d[other])
                d[h] = len(word)
        return ans
Java实现

Java实现

class Solution {
    public int maxProduct(String[] words) {
        Map<Integer, Integer> map = new HashMap<>();
        int ans = 0;
        for (String word: words) {
            int h = hash(word), n = word.length();
            if (map.containsKey(h) && map.get(h) >= n) continue;
            for (int other: map.keySet()) {
                if ((other & h) == 0) {
                    ans = Math.max(ans, map.get(other) * n);
                }
            }
            map.put(h, n);
        }
        return ans;
    }
    
    private int hash(String word) {
        int res = 0;
        for (int i=0; i < word.length(); i++) {
            res |= 1 << (word.charAt(i) - 'a');
        }
        return res;
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值