You are given an m x n
matrix board
, representing the current state of a crossword puzzle. The crossword contains lowercase English letters (from solved words), ' '
to represent any empty cells, and '#'
to represent any blocked cells.
A word can be placed horizontally (left to right or right to left) or vertically (top to bottom or bottom to top) in the board if:
- It does not occupy a cell containing the character
'#'
. - The cell each letter is placed in must either be
' '
(empty) or match the letter already on theboard
. - There must not be any empty cells
' '
or other lowercase letters directly left or right of the word if the word was placed horizontally. - There must not be any empty cells
' '
or other lowercase letters directly above or below the word if the word was placed vertically.
Given a string word
, return true
if word
can be placed in board
, or false
otherwise.
Example 1:
Input: board = [["#", " ", "#"], [" ", " ", "#"], ["#", "c", " "]], word = "abc" Output: true Explanation: The word "abc" can be placed as shown above (top to bottom).
Example 2:
Input: board = [[" ", "#", "a"], [" ", "#", "c"], [" ", "#", "a"]], word = "ac" Output: false Explanation: It is impossible to place the word because there will always be a space/letter above or below it.
Example 3:
Input: board = [["#", " ", "#"], [" ", " ", "#"], ["#", " ", "c"]], word = "ca" Output: true Explanation: The word "ca" can be placed as shown above (right to left).
Constraints:
m == board.length
n == board[i].length
1 <= m * n <= 2 * 105
board[i][j]
will be' '
,'#'
, or a lowercase English letter.1 <= word.length <= max(m, n)
word
will contain only lowercase English letters.
Implement a function match(A, s)
which returns true
if matrix A
matches word s
horizontally. To handle the vertical case, we can simply use B
as the transpose of A
, and check match(B, s)
.
Within match
function, we check line by line. For each line, we scan each segment surrounded by #
s or line boundaries. For each segment, we check if it equals string s
from left to right, or from right to left.
The time complexity is O(MN)
because each cell is matched at most 4 times.
// OJ: https://leetcode.com/problems/check-if-word-can-be-placed-in-crossword/
// Author: github.com/lzl124631x
// Time: O(MN)
// Space: O(MN)
class Solution {
bool same(vector<char> &A, int first, int last, string &s) { // returns true if `A[first..last]` equals `s` or reversed `s`.
if (last - first + 1 != s.size()) return false;
int i = 0, N = s.size();
while (i < N && (A[first + i] == ' ' || A[first + i] == s[i])) ++i; // match from left to right
if (i == N) return true;
for (i = 0; i < N && (A[last - i] == ' ' || A[last - i] == s[i]);) ++i; // match from right to left
return i == N;
}
bool match(vector<vector<char>> &A, string s) { // returns `true` if matrix `A` matches string `s` horizontally
int N = A[0].size();
for (auto &row : A) {
for (int i = 0; i < N; ) {
while (i < N && row[i] == '#') ++i;
int start = i;
while (i < N && row[i] != '#') ++i;
if (same(row, start, i - 1, s)) return true; // match `row[start..(i-1)]` with `s`.
}
}
return false;
}
public:
bool placeWordInCrossword(vector<vector<char>>& A, string s) {
int M = A.size(), N = A[0].size();
vector<vector<char>> B(N, vector<char>(M)); // `B` is the transpose of `A`
for (int i = 0; i < M; ++i) {
for (int j = 0; j < N; ++ j) {
B[j][i] = A[i][j];
}
}
return match(A, s) || match(B, s);
}
};