public class Solution {
public int maxProduct(String[] words) {
int max = 0;
Arrays.sort(words, new Comparator<String>(){
public int compare(String a, String b){
return b.length()  a.length();
}
});
int[] masks = new int[words.length]; // alphabet masks
for(int i = 0; i < masks.length; i++){
for(char c: words[i].toCharArray()){
masks[i] = 1 << (c  'a');
}
}
for(int i = 0; i < masks.length; i++){
if(words[i].length() * words[i].length() <= max) break; //prunning
for(int j = i + 1; j < masks.length; j++){
if((masks[i] & masks[j]) == 0){
max = Math.max(max, words[i].length() * words[j].length());
break; //prunning
}
}
}
return max;
}
}
32ms Java AC solution


my python version:
def maxProduct(self, words): """ :type words: List[str] :rtype: int """ n = len(words) def my_cmp(a,b): return len(b)len(a) sorted_words = sorted(words, my_cmp)#seem not save time :( mask = [0]*n count = [0]*n begin_ord = ord('a') for i, w in enumerate(sorted_words): for c in w: mask[i] = 1<<ord(c)begin_ord count[i] += 1 max_len = 0 for i in range(n): if count[i]**2<max_len: continue for j in range(i+1, n): if mask[i]&mask[j]==0: multiple = count[i]*count[j] if multiple>max_len: max_len = multiple break return max_len

try to simplify it with Java 8:
Arrays.sort(words, (a, b) > b.length()  a.length()); int[] masks = new int[words.length]; for (int i = 0, len = words.length; i < len; i++) { for (int j = 0; j < words[i].length(); j++) { masks[i] = 1 << (words[i].charAt(j)  'a'); } } int max = 0; for (int i = 0, len = words.length; i < len; i++) { if (words[i].length() == 0) { continue; } for (int j = i + 1, minLen = max / words[i].length(); j < len && words[j].length() > minLen; j++) { if ((masks[i] & masks[j]) == 0 && words[i].length() * words[j].length() > max) { max = words[i].length() * words[j].length(); break; } } } return max;