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.

&nbsp;
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.


&nbsp;
Constraints:


	2 &lt;= words.length &lt;= 1000
	1 &lt;= words[i].length &lt;= 1000
	words[i] consists only of lowercase English letters.


class Solution:
    def maxProduct(self, words: List[str]) -> int:
        def check(w1, w2):
            for i in w1:
                if i in w2: 
                    return False
            return True
        
        n = len(words)   
        Max = 0
        for i in range(n):
            for j in range(i+1, n):
                if check(words[i], words[j]):
                    Max = max(Max, len(words[i])*len(words[j]))      
        return Max
class Solution {
    public int maxProduct(String[] words) {
        int n = words.length;
        int[] masks = new int[n];

        for (int i=0; i<n; i++)
            for (char c: words[i].toCharArray())
                masks[i] |= (1 << (c - 'a'));

        int largest = 0;
        for (int i=0; i<n-1; i++)
            for (int j=i+1; j<n; j++)
                if ((masks[i] & masks[j]) == 0)
                    largest = Math.max(largest, words[i].length() * words[j].length());

        return largest;
    }
}
class Solution {
public:
    int maxProduct(vector<string>& words) {
        vector<unordered_set<char>> st;
        int res =0;
        for(string s : words){
            unordered_set<char> temp;
            for(char c : s){
                temp.insert(c);
            }
            st.push_back(temp);
        }
        for(int i = 0;i<words.size();i++){
            for(int j =0;j<i;j++){
                bool flag = false;
                for(auto val : st[i]){
                    if(st[j].find(val) != st[j].end()){
                        flag = true;
                        break;
                    }
                }
                if(flag == false) {
                    int prd = words[i].length() * words[j].length();
                    res =max(res, prd);
                }
            }
        }
        return res;
    }
};
/**
 * @param {string[]} words
 * @return {number}
 */
var maxProduct = function(words) {
    words.sort((a, b) => b.length - a.length);
    
    const m = new Map();
    for(let word of words) {
        if(m.has(word)) continue;
        const alpha = new Array(26).fill(0);
        for(let w of word) {
            let idx = w.charCodeAt(0) - 'a'.charCodeAt(0);
            alpha[idx] = 1;
        }
        m.set(word, parseInt(alpha.join(''), 2));
    }
    
    const hasCommonLetters = (a, b) => {
        const sb = m.get(b);
        const sa = m.get(a);
        return (sa & sb) != 0;
    }
    let ans = 0, len = words.length;
    for(let i = 0; i < len; i++) {
        for(let j = i + 1; j < len; j++) {
            if(!hasCommonLetters(words[i], words[j])) {
                ans = Math.max(ans, words[i].length * words[j].length);
            }
        }
    }
    return ans;
};
Maximum Product of Word Lengths