#3799

Word Squares II

Medium
ArrayStringBacktrackingSortingEnumerationHash MapArray
LeetCode ↗

Approaches

Brute ForceOptimal
Complexity Comparison
Brute ForceOptimal Solution
Time
O(n²)
O(n)
Space
O(1)
O(n)
💡

Intuition

Time O(n)Space O(n)

Use a backtracking approach to build word squares incrementally, ensuring at each step that the current configuration can still lead to a valid square.

⚙️

Algorithm

3 steps
  1. 1Step 1: Create a prefix map to store words by their prefixes.
  2. 2Step 2: Use backtracking to build the word square row by row, checking prefixes against the map.
  3. 3Step 3: If a valid square is formed, add it to the result list.
solution.py20 lines
1from collections import defaultdict
2
3def wordSquares(words):
4    def backtrack(square):
5        if len(square) == 4:
6            result.append(square[:])
7            return
8        prefix = ''.join([square[i][len(square)] for i in range(len(square))])
9        for word in prefix_map[prefix]:
10            square.append(word)
11            backtrack(square)
12            square.pop()
13
14    prefix_map = defaultdict(list)
15    for word in words:
16        for i in range(1, 5):
17            prefix_map[word[:i]].append(word)
18    result = []
19    backtrack([])
20    return sorted(result)

Complexity note: The complexity is primarily due to the prefix map and backtracking, allowing efficient pruning of invalid paths.

  • 1Word squares depend on prefix matching.
  • 2Backtracking allows efficient exploration of valid configurations.

Solutions and explanations are original Tejav content. Problem titles © LeetCode — use the LeetCode button above for the full problem statement.