Welcome to Subscribe On Youtube

318. Maximum Product of Word Lengths

Description

Given a string array words, return the maximum value of length(word[i]) * length(word[j]) where the two words do not share common letters. If no such two words exist, return 0.

 

Example 1:

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

Example 2:

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

Example 3:

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

 

Constraints:

  • 2 <= words.length <= 1000
  • 1 <= words[i].length <= 1000
  • words[i] consists only of lowercase English letters.

Solutions

Solution 1: Bit Manipulation

The problem requires us to find two strings without common letters, so that their length product is maximized. We can represent each string with a binary number $mask[i]$, where each bit of this binary number indicates whether the string contains a certain letter. If two strings do not have common letters, then the bitwise AND result of the two binary numbers corresponding to these strings is $0$, that is, $mask[i] \& mask[j] = 0$.

We traverse each string. For the current string $words[i]$ we are traversing, we first calculate the corresponding binary number $mask[i]$, and then traverse all strings $words[j]$ where $j \in [0, i)$. We check whether $mask[i] \& mask[j] = 0$ holds. If it holds, we update the answer to $\max(ans, |words[i]| \times |words[j]|)$.

After the traversal, we return the answer.

The time complexity is $O(n^2 + L)$, and the space complexity is $O(n)$. Here, $n$ is the length of the string array $words$, and $L$ is the sum of the lengths of all strings in the string array.

  • class Solution {
        public int maxProduct(String[] words) {
            int n = words.length;
            int[] mask = new int[n];
            int ans = 0;
            for (int i = 0; i < n; ++i) {
                for (char c : words[i].toCharArray()) {
                    mask[i] |= 1 << (c - 'a');
                }
                for (int j = 0; j < i; ++j) {
                    if ((mask[i] & mask[j]) == 0) {
                        ans = Math.max(ans, words[i].length() * words[j].length());
                    }
                }
            }
            return ans;
        }
    }
    
  • class Solution {
    public:
        int maxProduct(vector<string>& words) {
            int n = words.size();
            int mask[n];
            memset(mask, 0, sizeof(mask));
            int ans = 0;
            for (int i = 0; i < n; ++i) {
                for (char& c : words[i]) {
                    mask[i] |= 1 << (c - 'a');
                }
                for (int j = 0; j < i; ++j) {
                    if ((mask[i] & mask[j]) == 0) {
                        ans = max(ans, (int) (words[i].size() * words[j].size()));
                    }
                }
            }
            return ans;
        }
    };
    
  • class Solution:
        def maxProduct(self, words: List[str]) -> int:
            n = len(words)
            mask = [0] * n
            for i, word in enumerate(words):
                for ch in word:
                    mask[i] |= 1 << (ord(ch) - ord('a'))
            ans = 0
            for i in range(n - 1):
                for j in range(i + 1, n):
                    if mask[i] & mask[j] == 0:
                        ans = max(ans, len(words[i]) * len(words[j]))
            return ans
    
    ############
    
    class Solution(object):
      def maxProduct(self, words):
        """
        :type words: List[str]
        :rtype: int
        """
        bitmap = [0] * len(words)
        mask = 0x01
        ans = 0
        for i in range(0, len(words)):
          word = words[i]
          for c in word:
            bitmap[i] |= (mask << (ord(c) - ord('a')))
        for i in range(0, len(words)):
          for j in range(0, i):
            if bitmap[i] & bitmap[j] == 0:
              ans = max(ans, len(words[i]) * len(words[j]))
    
        return ans
    
    
  • func maxProduct(words []string) (ans int) {
    	n := len(words)
    	mask := make([]int, n)
    	for i, s := range words {
    		for _, c := range s {
    			mask[i] |= 1 << (c - 'a')
    		}
    		for j, t := range words[:i] {
    			if mask[i]&mask[j] == 0 {
    				ans = max(ans, len(s)*len(t))
    			}
    		}
    	}
    	return
    }
    
  • function maxProduct(words: string[]): number {
        const n = words.length;
        const mask: number[] = Array(n).fill(0);
        let ans = 0;
        for (let i = 0; i < n; ++i) {
            for (const c of words[i]) {
                mask[i] |= 1 << (c.charCodeAt(0) - 'a'.charCodeAt(0));
            }
            for (let j = 0; j < i; ++j) {
                if ((mask[i] & mask[j]) === 0) {
                    ans = Math.max(ans, words[i].length * words[j].length);
                }
            }
        }
        return ans;
    }
    
    

All Problems

All Solutions