HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonModerate

Maximum product of word lengths in Python

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
maximumproductwordpythonlengths

Problem

Problems was to calculate maximum product of word lengths:


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.

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


My answer is correct and passed all the test cases. I am looking to get some code review on this.

class Solution(object):
def maxProduct(self, words):
"""
maximum value of length(word[i]) * length(word[j]) where the two words do not share common letters
>> maxProduct(["eae", "ea", "aaf", "bda", "fcf", "dc", "ac", "ce", "cefde", "dabae"])
>> 15
"""
max_product = 0
words = sorted(words, key=len, reverse=True)
for index, j in enumerate(words):
for i in words[index + 1:]:
count = 0
for k in i:
if k in j:
count = 1
break
if not count:
m = len(j)
n = len(i)
word_product = m * n
if ((m == n) or (m > n and n == m - 1)) and word_product > max_product:
return word_product
if word_product > max_product:
max_product = word_product
return max_product

Solution

My solution is quite different, let me explain it:

At first I define a small helper to check if two words have any letter in common, it may also be in-lined, but I like small functions.

def common(a, b):
    """
    >>> common("hello", "hi")
    {'h'}
    """
    return set(a) & set(b)


Then I define the relevant score function for the strings, as you see, after defining our criteria we are almost done.

def product_score(w1, w2):
    """
    >>> product_score("foo", "bar")
    9
    >>> product_score("foo", "fuu")
    0
    """
    return 0 if common(w1, w2) else len(w1) * len(w2)


The last step is very easy. We already know the criteria, so we can just map it over the combination of 2 of the input list and take the max:

def maxProduct(words):
    """
    Maximum value of length(word[i]) * length(word[j]) where the two words do not share common letters.

    >>> maxProduct(["eae", "ea", "aaf", "bda", "fcf", "dc", "ac", "ce", "cefde", "dabae"])
    15
    """
    return max(product_score(w1, w2) 
                   for (w1, w2) in itertools.combinations(words, 2))


I think my solution is more readable, mainly because it uses smaller functions and because it uses already existing wheels (standard library modules).

Code Snippets

def common(a, b):
    """
    >>> common("hello", "hi")
    {'h'}
    """
    return set(a) & set(b)
def product_score(w1, w2):
    """
    >>> product_score("foo", "bar")
    9
    >>> product_score("foo", "fuu")
    0
    """
    return 0 if common(w1, w2) else len(w1) * len(w2)
def maxProduct(words):
    """
    Maximum value of length(word[i]) * length(word[j]) where the two words do not share common letters.

    >>> maxProduct(["eae", "ea", "aaf", "bda", "fcf", "dc", "ac", "ce", "cefde", "dabae"])
    15
    """
    return max(product_score(w1, w2) 
                   for (w1, w2) in itertools.combinations(words, 2))

Context

StackExchange Code Review Q#115362, answer score: 10

Revisions (0)

No revisions yet.