318. Maximum Product of Word Lengths

Description

Given a string array words, find the maximum value of length(word[i]) * length(word[j]) where the two words do not share common letters. You may assume that each word will contain only lower case letters. If no such two words exist, return 0.

Example 1:

Input: ["abcw","baz","foo","bar","xtfn","abcdef"]
Output: 16
Explanation: The two words can be `"abcw", "xtfn".

Example 2:

Input: ["a","ab","abc","d","cd","bcd","abcd"]
Output: 4
Explanation: The two words can be `"ab", "cd".

Example 3:

Input: ["a","aa","aaa","aaaa"]
Output: 0
Explanation: No such pair of words.

Solution

HashMap, O(N ^ 2 * L), S(N ^ 2)

Use char2Index to keep the word indexes of words that contains char x.
For each word, use noCommon set to keep no common word indexes. Iterate each char c in word[i], remove the indexes of char2Index.get(c) from noCommon set. Finally noCommon contains no common indexes only. Then calculate maxProduct.

class Solution {
    public int maxProduct(String[] words) {
        if (words == null || words.length < 2) {
            return 0;
        }
        
        Map<Character, Set<Integer>> char2Index = new HashMap<>();
        int n = words.length;
        
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < words[i].length(); ++j) {
                char c = words[i].charAt(j);
                
                if (!char2Index.containsKey(c)) {
                    char2Index.put(c, new HashSet<>());
                }
                
                char2Index.get(c).add(i);
            }
        }
        
        int maxProduct = 0;
        
        for (int i = 0; i < n; ++i) {
            Set<Integer> noCommon = new HashSet<>();
            for (int j = 0; j < n; ++j) {   // add [0, n - 1] initially
                noCommon.add(j);
            }
            
            for (int j = 0; j < words[i].length(); ++j) {
                noCommon.removeAll(char2Index.get(words[i].charAt(j)));
            }
            
            for (int j : noCommon) {
                maxProduct = Math.max(
                    words[i].length() * words[j].length(), maxProduct);
            }
        }
        
        return maxProduct;
    }
}

Bit-manipulation, O(n ^ 2), S(n)

Because words only contains lowercase letters (26 in total), we could use 1 bit to mark each char appearance. Then we could use just one int bits to represent a word. If words[i] and words[j] share no char, bits[i] & bits[j] should equal to 1.

class Solution {
    public int maxProduct(String[] words) {
        if (words == null || words.length < 2) {
            return 0;
        }
        
        int n = words.length;
        int[] bits = new int[n];
        // use bits[i] to represent words[i]
        // each bit is a mark of a character appearance
        for (int i = 0; i < n; ++i) {
            String s = words[i];
            for (int j = 0; j < s.length(); ++j) {
                bits[i] |= 1 << (s.charAt(j) - 'a');
            }
        }
        
        int maxProduct = 0;
        for (int i = 0; i < n - 1; ++i) {
            for (int j = i + 1; j < n; ++j) {
                if ((bits[i] & bits[j]) == 0) {
                    maxProduct = Math.max(
                        words[i].length() * words[j].length(), maxProduct);
                }
            }
        }
        
        return maxProduct;
    }
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容