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

最大单词长度乘积

  • 318.最大单词长度乘积
    • 题目描述
    • 思路
      • 位运算
        • Python实现
        • Java实现


318.最大单词长度乘积

题目描述

最大单词长度乘积


思路

位运算

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

Python实现

力扣每日一题2021-11-17最大单词长度乘积_第1张图片

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实现

力扣每日一题2021-11-17最大单词长度乘积_第2张图片

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;
    }
}

你可能感兴趣的:(leetcode每日一题,leetcode)