题目描述:给你一个字符串数组 words ,找出并返回 length(words[i]) * length(words[j]) 的最大值,并且这两个单词不含有公共字母。如果不存在这样的两个单词,返回 0 。
示例 1:
输入:words = [“abcw”,“baz”,“foo”,“bar”,“xtfn”,“abcdef”]
输出:16
解释:这两个单词为 “abcw”, “xtfn”。
示例 2:
输入:words = [“a”,“ab”,“abc”,“d”,“cd”,“bcd”,“abcd”]
输出:4
解释:这两个单词为 “ab”, “cd”。
示例 3:
输入:words = [“a”,“aa”,“aaa”,“aaaa”]
输出:0
解释:不存在这样的两个单词。
提示:
2 <= words.length <= 1000
1 <= words[i].length <= 1000
words[i] 仅包含小写字母
package leetcode;
public class p318 {
public static void main(String[] args) {
String[] words={"a","aa","aaa","aaaa"};
System.out.println(maxProduct2(words));
}
/**
* 不出意外地时间超限
*思路:使用双重遍历遍历所有字符串,判断是否含有重复字母,若没有则与现在最大的比较大小,保存大的那个
* 时间复杂度O(n3) 空间复杂度O(1)
*/
public static int maxProduct(String[] words) {
int answer=0;
for (int i=0;i<words.length;i++){
for (int j=i+1;j<words.length;j++) {
Boolean contain = isContain(words[i], words[j]);
if (!contain) {
int tmp=words[i].length() * words[j].length();
if (answer>tmp)
continue;
else
answer=tmp;
}
}
}
return answer;
}
// 判断这个两个字符串中是否含有相同的字符
public static Boolean isContain(String a,String b){
if (a.length()<b.length()){
for (int i=0;i<a.length();i++){
if (b.contains(String.valueOf(a.charAt(i)))){
return true;
}
}
}else {
for (int i=0;i<b.length();i++){
if (a.contains(String.valueOf(b.charAt(i)))){
return true;
}
}
}
return false;
}
/**
* 思路:位运算的方式,将单词用一个int类型表示,低26位上有1表示出现过。在判断两个单词是否有字母重复时只要与一下就行了
* 时间复杂度o(n2) 空间复杂度O(n)
*/
public static int maxProduct2(String[] words) {
int[] masks=new int[words.length]; // 表示单词数组的掩码数组
for (int i=0;i< words.length;i++){
int mask=0;
for (int j=0;j<words[i].length();j++){ // 经过这个循环就能得到第i个单词的掩码
int left=words[i].charAt(j)-'a';
mask|=1<<left;
}
masks[i]=mask;
}
int answer=0;
for (int i=0;i< words.length;i++){
for (int j=i+1;j< words.length;j++){
if ((masks[i]&masks[j])==0){ // 如果两个单词没有相同的字母,则将其与现有最大的进行比较
answer=Math.max(answer,words[i].length()*words[j].length());
}
}
}
return answer;
}
}
总结:当要判断两个集合中是否含有相同的元素时,可以将集合中的元素使用掩码来表示,只要使用一次与运算就可以知道两个集合中是否含有相同的元素。