LeetCode 318. Maximum Product of Word Lengths

简介: 给定一个字符串数组 words,找到 length(word[i]) * length(word[j]) 的最大值,并且这两个单词不含有公共字母。你可以认为每个单词只包含小写字母。如果不存在这样的两个单词,返回 0。

v2-ddacb5f239d1ef966b65953bf8bb870f_1440w.jpg

Description



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:


Input: ["abcw","baz","foo","bar","xtfn","abcdef"]
Output: 16 
Explanation: The two words can be "abcw", "xtfn".


Example 2:


Input: ["a","ab","abc","d","cd","bcd","abcd"]
Output: 4 
Explanation: The two words can be "ab", "cd".


Example 3:


Input: ["a","aa","aaa","aaaa"]
Output: 0 
Explanation: No such pair of words.


描述



给定一个字符串数组 words,找到 length(word[i]) * length(word[j]) 的最大值,并且这两个单词不含有公共字母。你可以认为每个单词只包含小写字母。如果不存在这样的两个单词,返回 0。


示例 1:


输入: ["abcw","baz","foo","bar","xtfn","abcdef"]
输出: 16 
解释: 这两个单词为 "abcw", "xtfn"。


示例 2:


输入: ["a","ab","abc","d","cd","bcd","abcd"]
输出: 4 
解释: 这两个单词为 "ab", "cd"。


示例 3:


输入: ["a","aa","aaa","aaaa"]
输出: 0 
解释: 不存在这样的两个单词。


思路



  • 基本思路很简单:对给定的单词两两组合,如果这两个单词没有相同的字符,记下者两个单词长度值的乘积,返回最大值。
  • 如何判断两个单词是否使用了相同的单词:我们使用位运算,整形有 32 位,字符只有 26 个。
  • 我们让二进制的数第一位表示 a ,第二位表示 b ... 第 26 位表示 z 。如果某个字母在给定的单词中出现了,我们记字母对应位置的二进制位 1 。
  • 如果两个单词没有使用相同的字母,那么这两个单词对应的二进制按位与一定为 0 ,因为两个单词没有使用相同的字母,所以二进制中的 1 都是错开的。


# -*- coding: utf-8 -*-
# @Author:             何睿
# @Create Date:        2019-02-23 13:14:24
# @Last Modified by:   何睿
# @Last Modified time: 2019-02-23 14:24:48
import itertools
class Solution:
    def maxProduct(self, words) -> int:
        # bits 是字典,键为单词 word 对应的二进制码,值为一个二进制码对应的最长单词
        # 最长单词:单词 a,aa,aaa,aaaa,对应的二进制码都是 0b1,为了获得最大的乘积
        # 我们取最长的单词 aaaa,所以 0b1 对应 4
        bits = {}
        for word in words:
            #  获取单词单词对应的 二进制码,有点类似哈希,但是不完全相同
            bit = self.getBit(word)
            # 建立键值对,这样可以避免多次 len(word)
            # 值为最长单词的长度
            bits[bit] = max(bits.get(bit, 0), len(word))
        # 对一个列表的所有元素进行两两组合
        # 也可以用循环,如 maxProduct2 中示例
        # 但是在 python 中 itertools.combinations 更快
        com = itertools.combinations(bits.keys(), r=2)
        # 对所有组合中单词没有重复的求乘积,这里也可以写成循环的形式
        # 但是在 python 中列表解析式的执行速度更快
        return max([bits[x] * bits[y] for x, y in com if x & y == 0] or [0])
    def maxProduct2(self, words) -> int:
        res = 0
        bits = [self.getBit(word) for word in words]
        for i in range(len(words)):
            for j in range(i + 1, len(words)):
                if bits[i] & bits[j] == 0:
                    res = max(res, len(words[i]) * len(words[j]))
        return res
    def getBit(self, word):
        bit = 0
        # 按位或
        # 字母 a 对一二进制第 1 位,b 对应第 2 位 ... z 对应 第 26 位
        for char in word:
            bit = bit | (1 << (ord(char) - 97))
        return bit


源代码文件在 这里



目录
相关文章
|
5月前
Leetcode 53.Maximum Subarray
题意简单,给出一个数组,求出其中最大的子数组和。 这种简单题目背后蕴藏着很巧妙的解题方法。其实只需要遍历一次数组就可以求得解。 思路是这样的,你想想看,如果一段子数组的和是负数, 那么这一段子数组不可能是最大和数组的一部分,丢掉重新从下一个位置开始选。
27 0
LeetCode 104. 二叉树的最大深度 Maximum Depth of Binary Tree
LeetCode 104. 二叉树的最大深度 Maximum Depth of Binary Tree
|
算法
LeetCode 414. Third Maximum Number
给定一个非空数组,返回此数组中第三大的数。如果不存在,则返回数组中最大的数。要求算法时间复杂度必须是O(n)。
66 0
LeetCode 414. Third Maximum Number
LeetCode 290. Word Pattern
给定一种 pattern(模式) 和一个字符串 str ,判断 str 是否遵循相同的模式。 这里的遵循指完全匹配,例如, pattern 里的每个字母和字符串 str 中的每个非空单词之间存在着双向连接的对应模式。
31 0
LeetCode 290. Word Pattern
LeetCode 212. Word Search II
给定一个二维网格 board 和一个字典中的单词列表 words,找出所有同时在二维网格和字典中出现的单词。 单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母在一个单词中不允许被重复使用。
55 0
LeetCode 212. Word Search II
LeetCode 164. Maximum Gap
给定一个无序的数组,找出数组在排序之后,相邻元素之间最大的差值。 如果数组元素个数小于 2,则返回 0。
54 0
LeetCode 164. Maximum Gap
LeetCode 152. Maximum Product Subarray
给定一个整数数组 nums ,找出一个序列中乘积最大的连续子序列(该序列至少包含一个数)。
31 0
LeetCode 152. Maximum Product Subarray
|
索引
LeetCode 79. Word Search
给定一个2D板和一个单词,找出该单词是否存在于网格中。 该单词可以由顺序相邻的单元的字母构成,其中“相邻”单元是水平或垂直相邻的单元。 相同的字母单元格不得多次使用。
49 0
LeetCode 79. Word Search
LeetCode 53. Maximum Subarray
给定整数数组nums,找到具有最大总和的子数组(数组要求连续)并且返回数组的和,给定的数组包含至少一个数字。
32 0
|
Python
[Leetcode][python]Maximum Subarray/最大子序和
题目大意 由 N 个整数元素组成的一维数组 (A[0], A[1],…,A[n-1], A[n]),这个数组有很多连续子数组,那么其中数组之和的最大值是什么呢? 子数组必须是连续的。 不需要返回子数组的具体位置。 数组中包含:正整数,零,负整数。
80 0