力扣每日一题--318.最大单词长度乘积

发布时间 2023-11-09 09:43:41作者: 翻斗花园数据分析师

318.最大单词长度乘积

题目:

给你一个字符串数组 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 
解释:不存在这样的两个单词。

解答:

class Solution:
    def maxProduct(self, words: List[str]) -> int:
        #首先初始化数组,以便后面存储每个单词计算后的值
        mask = [0] * len(words)
        ans = 0 #将最大值初始化为0 
        for i, s in enumerate(words):
            #利用enumerate便利各个单词
            #遍历整个单词,c即当前字母
            for c in s:
                '''
                以下是重点,解释了为什么要用位运算计算公共字母,我们先理解代码,再思考原因
                1、我利用了ASCII码值的特性,例如‘c’-‘a’==2,‘d’-‘a’==1
                2、以下的代码就是位运算,(ord(c)-ord(a))
                即是遍历该单词的字母减去a得到相对距离,得到值后往左移动这个值
                    ps:例如abce,输出的数是10111,bcf就是100110,
                3、使用ascii码值标记每个单词,在相对比较时就不需要使用find实现,
                并且节约时间,仅仅需要比较两者的数值中同一位上是否都有1,都有1表示有相同的字母
                4、|=,就是按位或运算符:只要对应的二个二进位有一个为1时,结果位就为1。
                5、<<的意思是向左移位的意思,并且(ord(c) - ord("a"))得到的就是移位的数量
                '''
                
                mask[i] |= 1 << (ord(c) - ord("a")) # ord函数表示ascii码值,
            for j, t in enumerate(words[:i]):
                if (mask[i] & mask[j]) == 0:
                    ans = max(ans, len(s) * len(t))
        return ans

图片

上面这些可以理解一下,接下来就是解释解法:

1、因为有26位字母,定义第一位a为0,计算相对位置,b即为1,d即为3,以此类推,设定字母的位置

2、只要同一个字母位上,两个单词都有1即表示两个单词有相同的字母