Similar Problems
Similar Problems not available
Word Squares - Leetcode Solution
Companies:
LeetCode: Word Squares Leetcode Solution
Difficulty: Hard
Topics: string backtracking array
The Word Squares problem on Leetcode requires building a word square with a given set of words. First, let's understand what a word square is.
A Word Square is a set of words arranged in a square such that the words in each row and column are the same. For instance, the set of words ["area", "roam", "emit", "mire"] can be arranged into a word square of the following form:
a r e a
r o a m
e m i t
a m i r
In this particular example, the first row and first column have the same word "area", the second row and second column have the word "roam", and so on.
To solve this problem, we need to come up with a recursive solution that builds a word square one row at a time. The first step is to build the first row of the word square by taking each word one at a time and then recursively building the remaining rows.
The recursive function takes in the current state of the word square and an index indicating which word to use for the current row.
def build_word_squares(words):
n = len(words[0])
results = []
word_map = build_word_map(words)
build_word_square([], 0, n, word_map, results)
return results
The words
argument is a list of words to build the word square from, n
is the length of each word, results
is a list to hold all the valid word squares that are built, and word_map
is a dictionary containing the words grouped by their prefixes. We'll come back to word_map
later.
The build_word_square
function is the recursive function that builds a word square row by row. Let's take a closer look at how it works.
def build_word_square(square, row, n, word_map, results):
if row == n:
results.append(square)
return
prefix = ''.join(square[j][row] for j in range(row))
if prefix in word_map:
for word in word_map[prefix]:
build_word_square(square + [word], row + 1, n, word_map, results)
The function takes in square
which is the current state of the word square, row
which is the current row we are building, word_map
which is the dictionary of words grouped by prefixes, and results
, which is the list to hold all the valid word squares that are built.
The base case is when we have completed building the word square, i.e., when row
is equal to n
. At this point, we append the square
to results
and return.
Next, we compute the prefix
for the current row. The prefix
is a string consisting of the first row
letters of each word in the current square
. This is used to check if there are any words that start with this prefix.
We check if the prefix exists in the word_map
. If it does, we iterate over all the words in the word_map
that start with this prefix, and recursively call build_word_square
with the new square
which includes the current word
, row
incremented by 1, and the other arguments.
Let's implement the build_word_map
function, which builds a dictionary mapping prefixes to a list of words that start with that prefix.
def build_word_map(words):
word_map = defaultdict(list)
for word in words:
for i in range(len(word)):
word_map[word[:i+1]].append(word)
return word_map
The build_word_map
function takes in the list of words
and returns a dictionary where the keys are the prefixes of the words in the list, and the values are lists of words that start with that prefix.
Finally, we can put everything together and test the solution with a sample input.
words = ["area", "roam", "emit", "mire"]
print(build_word_squares(words))
# Output: [['aera', 'roam', 'emit', 'mire'], ['area', 'roam', 'emit', 'amir']]
The output is a list of all the valid word squares that can be built with the given words.
Word Squares Solution Code
1