318. Maximum Product of Word Lengths
An example of the Bit Masking Technique

Hi! My name is Nhut Nguyen. I am a software engineer and a writer in Copenhagen, Denmark.
Learn more about me at nhutnguyen.com
Search for a command to run...
An example of the Bit Masking Technique

Hi! My name is Nhut Nguyen. I am a software engineer and a writer in Copenhagen, Denmark.
Learn more about me at nhutnguyen.com
No comments yet. Be the first to comment.
A simple example of using C++ switch

Two dynamic programming techniques to solve Leetcode 120. Triangle. One has space complexity O(n^2). The other is O(n).

An example of using a sliding window approach and an unordered map to track character positions

A simple C++ solution to Leetcode 1695. Maximum Erasure Value using a sliding window approach and prefix sums.

Strategies to avoid them will help you excel in your following technical interview

Given a string array words, return the maximum value of length(word[i]) * length(word[j]) where the two words do not share common letters. If no such two words exist, return 0.
Input: words = ["abcw","baz","foo","bar","xtfn","abcdef"]
Output: 16
Explanation: The two words can be "abcw", "xtfn".
Input: words = ["a","ab","abc","d","cd","bcd","abcd"]
Output: 4
Explanation: The two words can be "ab", "cd".
Input: words = ["a","aa","aaa","aaaa"]
Output: 0
Explanation: No such pair of words.
2 <= words.length <= 1000.
1 <= words[i].length <= 1000.
words[i] consists only of lowercase English letters.
For each words[i], for all words[j] with j > i, check if they do not share common letters and compute the product of their lengths.
#include <vector>
#include <iostream>
using namespace std;
int maxProduct(vector<string>& words) {
int maxP = 0;
for (int i = 0; i < words.size(); i++) {
vector<bool> visited(26, false);
for (char c : words[i]) {
visited[c - 'a'] = true;
}
for (int j = i + 1; j < words.size(); j++) {
bool found = false;
for (char c : words[j]) {
if (visited[c - 'a']) {
found = true;
break;
}
}
if (!found) {
maxP = max(maxP, (int) (words[i].length() * words[j].length()));
}
}
}
return maxP;
}
int main() {
vector<string> words{"abcw","baz","foo","bar","xtfn","abcdef"};
cout << maxProduct(words) << endl;
words = {"a","ab","abc","d","cd","bcd","abcd"};
cout << maxProduct(words) << endl;
words = {"a","aa","aaa","aaaa"};
cout << maxProduct(words) << endl;
}
Output:
16
4
0
Runtime: O(N^2**M), where N = words.length, M = avg(words[i].length).
Extra space: O(1).
You can map a words[i] to the bit representation of an integer n by their characters like the following:
If the word words[i] contains the letter 'a', the bit at position 0 of n is 1.
If the word words[i] contains the letter 'b', the bit at position 1 of n is 1.
...
If the word words[i] contains the letter 'z', the bit at position 25 of n is 1.
Then to check if two words have common letters, you just perform the bitwise operator AND on them.
For Example 1:
The word "abcw" is mapped to 00010000000000000000000111.
The word "baz" is mapped to 10000000000000000000000011.
"abcw" & "baz" = 00000000000000000000000011. This value is not zero, which means they have common letters.
This technique is called bit masking.
#include <vector>
#include <iostream>
using namespace std;
int maxProduct(vector<string>& words) {
int maxP = 0;
vector<int> mask(words.size());
for (int i = 0; i < words.size(); i++) {
for (char c : words[i]) {
mask[i] |= 1 << (c - 'a');
}
for (int j = 0; j < i; j++) {
if ((mask[j] & mask[i]) == 0) {
maxP = max(maxP, (int) (words[i].length() * words[j].length()));
}
}
}
return maxP;
}
int main() {
vector<string> words{"abcw","baz","foo","bar","xtfn","abcdef"};
cout << maxProduct(words) << endl;
words = {"a","ab","abc","d","cd","bcd","abcd"};
cout << maxProduct(words) << endl;
words = {"a","aa","aaa","aaaa"};
cout << maxProduct(words) << endl;
}
Output:
16
4
0
Runtime: O(N^2), where N = words.length.
Extra space: O(N).
Thanks for reading. Feel free to share your thought about my content and check out my FREE book “10 Classic Coding Challenges”.