题目要求

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.

有一个字符串数组,从该字符串数组中找到两个字符串,要求满足这两个字符串之间没有相同的字母,同时它们的长度的乘积最大。

思路和代码

这道题的重点在于如何优化字符串的比较。直观的来说,我们无法避开复杂度为O(n^2)的循环因为必须进行两两比较才能识别出最大的乘积。但是我们可以优化字符串的比较。

既然只需要知道两个字符串是否有相同的字母,那么我们可以采用一种数据结构将每个单词所有的字母记录下来。这里采用的是二进制数的形式。我们知道字母的数量不会超过26个,因此我们使用32位的整数来存储。将低26位的二进制数分别对应字母a-z,从而用二进制数实现一个简单的map。

因此单词ae对应的二进制数为00000000 00000000 00000000 00010001

那么比较两个单词是否有重复的字母只需要将二者的二进制形式进行&操作即可。如果没有重复字母,则结果应该为0.

public int maxProduct(String[] words) {
        int length = words.length;
        int[] wordToInt = new int[length];
        for(int i = 0 ; i<length ; i++){
            String tmp = words[i];
            int value = 0;
            for(int j = 0 ; j<tmp.length() ; j++){
                value |= (1<< (tmp.charAt(j) - 'a'));
            }
            wordToInt[i] = value;
        }
        
        int max = 0;
        for(int i = 0 ; i < length ; i++){
            for(int j = i+1 ; j<length ; j++){
                if((wordToInt[i] & wordToInt[j])==0){
                    max = Math.max(max, words[i].length() * words[j].length());
                }
            }
        }
        return max;
    }

clipboard.png
想要了解更多开发技术,面试教程以及互联网公司内推,欢迎关注我的微信公众号!将会不定期的发放福利哦~


raledong
2.7k 声望2k 粉丝

心怀远方,负重前行