leetcode 318. Maximum Product of Word Lengths

来源:互联网 发布:新闻资讯网站php源码 编辑:程序博客网 时间:2024/06/15 07:46

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:

Given ["abcw", "baz", "foo", "bar", "xtfn", "abcdef"]
Return 16
The two words can be "abcw", "xtfn".

Example 2:

Given ["a", "ab", "abc", "d", "cd", "bcd", "abcd"]
Return 4
The two words can be "ab", "cd".

Example 3:

Given ["a", "aa", "aaa", "aaaa"]
Return 0
No such pair of words.

Credits:
Special thanks to @dietpepsi for adding this problem and creating all test cases.

嘛,我用了很繁很繁时间复杂度很差的方法,居然AC了。

package leetcode;import java.util.HashMap;import java.util.HashSet;public class Maximum_Product_of_Word_Lengths_318 {public int maxProduct(String[] words) {int maxProduct=0;HashMap<String, HashSet<Character>> map=new HashMap<String, HashSet<Character>>();for(int i=0;i<words.length;i++){String word=words[i];char[] c=word.toCharArray();HashSet<Character> hashSet=new HashSet<Character>();for(int j=0;j<c.length;j++){hashSet.add(c[j]);}map.put(word, hashSet);}for (int i = 0; i < words.length; i++) {String word = words[i];int length1 = word.length();char[] cs = word.toCharArray();for (int nextI = i + 1; nextI < words.length; nextI++) {HashSet<Character> set = map.get(words[nextI]);boolean hasCommon=false;for (int j = 0; j < cs.length; j++) {char c=cs[j];if(set.contains(c)){hasCommon=true;break;}}if(hasCommon==false){int length2=words[nextI].length();int product=length1*length2;if(product>maxProduct){maxProduct=product;}}}}return maxProduct;}public static void main(String[] args) {// TODO Auto-generated method stubMaximum_Product_of_Word_Lengths_318 m=new Maximum_Product_of_Word_Lengths_318();String[] words=new String[]{"a", "aa", "aaa", "aaaa"};System.out.println(m.maxProduct(words));}}
让我们来看看大神的神奇方法!

public static int maxProduct2(String[] words) {if (words == null || words.length == 0)return 0;int len = words.length;int[] value = new int[len];for (int i = 0; i < len; i++) {String tmp = words[i];value[i] = 0;for (int j = 0; j < tmp.length(); j++) {value[i] |= 1 << (tmp.charAt(j) - 'a');}}int maxProduct = 0;for (int i = 0; i < len; i++){for (int j = i + 1; j < len; j++) {if ((value[i] & value[j]) == 0){int product=words[i].length() * words[j].length();if(product> maxProduct){maxProduct = words[i].length() * words[j].length();}}}}return maxProduct;}

思路是这样的:int 有32位,但是小写字母只有26位,因此我们可以使用 int 的低26位来表示 一个字符串包含有多少种小写字母。如果int最低位是1,那么意味着该字符串包含'a';如果int第二低位是1,那么意味着该字符串包含'b';如果int第三低位是0,那么意味着该字符串不包含'c‘........所以完全可以用一个整数来表示出该字符串包含了哪些小写字母。

如"abcd" 和 "aabbccdd" 字符串对应的整数都是 0000 ***0 1111,那么 0000 ***0 1111 & 0000 ***0 1111 = **** 1111 ,意味着这两个字符串存在相同字符。
另如"abcd" 和 "efgh"对应的整数分别是 0000 **** 0000 1111 和 0000 **** 1111 0000,那么 0000 **** 0000 1111 & 0000 **** 1111 0000 = 0000 **** 0000,意味着这两个字符串不存在相同字符。

原创粉丝点击