夯实算法-最大单词长度乘积

163 阅读2分钟

题目:最大单词长度乘积

给你一个字符串数组 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] 仅包含小写字母

解题思路

对于每一个字符串,不论该字符串有多长,它所包含的字母字符的种类不会超过26,前面也说了,本题关心的是字符串的字母种类,不关心各个字母的数量,那我们就可以使用一个32位的int整数来保存每个字符串的这种性质,故原来的字符串数组就变成了int数组

一个单词中最多有26个英文字母,所以用一个int型数存储一个单词中各个字母的出现情况。例如:单词中有a,则数字的第0位为1,否则为0;单词中有r,则数字的第15位为1,否则为0。按照这样的规则对每个单词的字母出现情况进行存储。之后遍历整个int型数组,如果两个数进行&运算的结果为0,则表示数字对应的单词无公共字母,否则有公共字母。

代码实现

public int maxProduct(String[] words) {
    int n = words.length;
    int[] bitNums = new int[n];
    for (int i = 0; i < n; i++) {
        bitNums[i] = getBitNum(words[i]);
    }
    int res = 0;
    for (int i = 0; i < n - 1; i++) {
        for (int j = i + 1; j < n; j++) {
            if ((bitNums[i] & bitNums[j]) == 0) {
                res = Math.max(res, words[i].length() * words[j].length());
            }
        }
    }
    return res;
}

private int getBitNum(String word) {
    int num = 0, len = word.length();
    for (int i = 0; i < len; i++) {
        num |= 1 << (word.charAt(i) - 'a');
    }
    return num;
}

运行结果

Snipaste_2023-05-10_22-31-37.png

复杂度分析

  • 空间复杂度:O(1)
  • 时间复杂度:O(n)

掘金(JUEJIN) 一起分享知识, Keep Learning!