Skip to content

Commit 12cc7d1

Browse files
committed
feat: add solutions to lc problem: No.2018
No.2018.Check if Word Can Be Placed In Crossword
1 parent d8bad90 commit 12cc7d1

File tree

6 files changed

+450
-2
lines changed

6 files changed

+450
-2
lines changed

solution/2000-2099/2018.Check if Word Can Be Placed In Crossword/README.md

Lines changed: 167 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,22 +67,188 @@
6767

6868
<!-- 这里可写通用的实现逻辑 -->
6969

70+
**方法一:枚举**
71+
72+
我们可以枚举矩阵的每个位置 $(i, j)$,判断是否能以该位置为起点,从左到右或从右到左放置单词 `word`,或者从上到下或从下到上放置单词 `word`
73+
74+
该位置能作为起点需要满足以下条件:
75+
76+
1. 如果要从从左到右放置单词 `word`,那么该位置必须是左边界,或者该位置左边的格子 `board[i][j - 1]``'#'`
77+
2. 如果要从从右到左放置单词 `word`,那么该位置必须是右边界,或者该位置右边的格子 `board[i][j + 1]``'#'`
78+
3. 如果要从从上到下放置单词 `word`,那么该位置必须是上边界,或者该位置上边的格子 `board[i - 1][j]``'#'`
79+
4. 如果要从从下到上放置单词 `word`,那么该位置必须是下边界,或者该位置下边的格子 `board[i + 1][j]``'#'`
80+
81+
在满足上述条件的情况下,我们可以从该位置开始,判断是否能放置单词 `word`。我们设计一个函数 $check(i, j, a, b)$,表示从位置 $(i, j)$ 开始,沿着方向 $(a, b)$ 放置单词 `word` 是否合法。如果合法,返回 `true`,否则返回 `false`
82+
83+
函数 $check(i, j, a, b)$ 的实现如下:
84+
85+
我们先获取当前方向的另一个边界位置 $(x, y)$,即 $(x, y) = (i + a \times k, j + b \times k)$,其中 $k$ 为单词 `word` 的长度。如果 $(x, y)$ 在矩阵内,并且 $(x, y)$ 的格子不是 `'#'`,则说明当前方向的另一个边界位置不是 `'#'`,因此不能放置单词 `word`,返回 `false`
86+
87+
否则,我们从位置 $(i, j)$ 开始,沿着方向 $(a, b)$ 遍历单词 `word`,如果遇到格子 `board[i][j]` 不是空格或者不是单词 `word` 的当前字符,说明不能放置单词 `word`,返回 `false`。如果遍历完单词 `word`,说明能放置单词 `word`,返回 `true`
88+
89+
时间复杂度 $O(m \times n)$,空间复杂度 $O(1)$。其中 $m$ 和 $n$ 分别为矩阵的行数和列数。
90+
7091
<!-- tabs:start -->
7192

7293
### **Python3**
7394

7495
<!-- 这里可写当前语言的特殊实现逻辑 -->
7596

7697
```python
77-
98+
class Solution:
99+
def placeWordInCrossword(self, board: List[List[str]], word: str) -> bool:
100+
def check(i, j, a, b):
101+
x, y = i + a * k, j + b * k
102+
if 0 <= x < m and 0 <= y < n and board[x][y] != '#':
103+
return False
104+
for c in word:
105+
if (
106+
i < 0
107+
or i >= m
108+
or j < 0
109+
or j >= n
110+
or (board[i][j] != ' ' and board[i][j] != c)
111+
):
112+
return False
113+
i, j = i + a, j + b
114+
return True
115+
116+
m, n = len(board), len(board[0])
117+
k = len(word)
118+
for i in range(m):
119+
for j in range(n):
120+
left_to_right = (j == 0 or board[i][j - 1] == '#') and check(i, j, 0, 1)
121+
right_to_left = (j == n - 1 or board[i][j + 1] == '#') and check(
122+
i, j, 0, -1
123+
)
124+
up_to_down = (i == 0 or board[i - 1][j] == '#') and check(i, j, 1, 0)
125+
down_to_up = (i == m - 1 or board[i + 1][j] == '#') and check(
126+
i, j, -1, 0
127+
)
128+
if left_to_right or right_to_left or up_to_down or down_to_up:
129+
return True
130+
return False
78131
```
79132

80133
### **Java**
81134

82135
<!-- 这里可写当前语言的特殊实现逻辑 -->
83136

84137
```java
138+
class Solution {
139+
private int m;
140+
private int n;
141+
private char[][] board;
142+
private String word;
143+
private int k;
144+
145+
public boolean placeWordInCrossword(char[][] board, String word) {
146+
m = board.length;
147+
n = board[0].length;
148+
this.board = board;
149+
this.word = word;
150+
k = word.length();
151+
for (int i = 0; i < m; ++i) {
152+
for (int j = 0; j < n; ++j) {
153+
boolean leftToRight = (j == 0 || board[i][j - 1] == '#') && check(i, j, 0, 1);
154+
boolean rightToLeft = (j == n - 1 || board[i][j + 1] == '#') && check(i, j, 0, -1);
155+
boolean upToDown = (i == 0 || board[i - 1][j] == '#') && check(i, j, 1, 0);
156+
boolean downToUp = (i == m - 1 || board[i + 1][j] == '#') && check(i, j, -1, 0);
157+
if (leftToRight || rightToLeft || upToDown || downToUp) {
158+
return true;
159+
}
160+
}
161+
}
162+
return false;
163+
}
164+
165+
private boolean check(int i, int j, int a, int b) {
166+
int x = i + a * k, y = j + b * k;
167+
if (x >= 0 && x < m && y >= 0 && y < n && board[x][y] != '#') {
168+
return false;
169+
}
170+
for (int p = 0; p < k; ++p) {
171+
if (i < 0 || i >= m || j < 0 || j >= n || (board[i][j] != ' ' && board[i][j] != word.charAt(p))) {
172+
return false;
173+
}
174+
i += a;
175+
j += b;
176+
}
177+
return true;
178+
}
179+
}
180+
```
181+
182+
### **C++**
183+
184+
```cpp
185+
class Solution {
186+
public:
187+
bool placeWordInCrossword(vector<vector<char>>& board, string word) {
188+
int m = board.size(), n = board[0].size();
189+
int k = word.size();
190+
auto check = [&](int i, int j, int a, int b) {
191+
int x = i + a * k, y = j + b * k;
192+
if (x >= 0 && x < m && y >= 0 && y < n && board[x][y] != '#') {
193+
return false;
194+
}
195+
for (char& c : word) {
196+
if (i < 0 || i >= m || j < 0 || j >= n || (board[i][j] != ' ' && board[i][j] != c)) {
197+
return false;
198+
}
199+
i += a;
200+
j += b;
201+
}
202+
return true;
203+
};
204+
for (int i = 0; i < m; ++i) {
205+
for (int j = 0; j < n; ++j) {
206+
bool leftToRight = (j == 0 || board[i][j - 1] == '#') && check(i, j, 0, 1);
207+
bool rightToLeft = (j == n - 1 || board[i][j + 1] == '#') && check(i, j, 0, -1);
208+
bool upToDown = (i == 0 || board[i - 1][j] == '#') && check(i, j, 1, 0);
209+
bool downToUp = (i == m - 1 || board[i + 1][j] == '#') && check(i, j, -1, 0);
210+
if (leftToRight || rightToLeft || upToDown || downToUp) {
211+
return true;
212+
}
213+
}
214+
}
215+
return false;
216+
}
217+
};
218+
```
85219
220+
### **Go**
221+
222+
```go
223+
func placeWordInCrossword(board [][]byte, word string) bool {
224+
m, n := len(board), len(board[0])
225+
k := len(word)
226+
check := func(i, j, a, b int) bool {
227+
x, y := i+a*k, j+b*k
228+
if x >= 0 && x < m && y >= 0 && y < n && board[x][y] != '#' {
229+
return false
230+
}
231+
for _, c := range word {
232+
if i < 0 || i >= m || j < 0 || j >= n || (board[i][j] != ' ' && board[i][j] != byte(c)) {
233+
return false
234+
}
235+
i, j = i+a, j+b
236+
}
237+
return true
238+
}
239+
for i := range board {
240+
for j := range board[i] {
241+
leftToRight := (j == 0 || board[i][j-1] == '#') && check(i, j, 0, 1)
242+
rightToLeft := (j == n-1 || board[i][j+1] == '#') && check(i, j, 0, -1)
243+
upToDown := (i == 0 || board[i-1][j] == '#') && check(i, j, 1, 0)
244+
downToUp := (i == m-1 || board[i+1][j] == '#') && check(i, j, -1, 0)
245+
if leftToRight || rightToLeft || upToDown || downToUp {
246+
return true
247+
}
248+
}
249+
}
250+
return false
251+
}
86252
```
87253

88254
### **...**

solution/2000-2099/2018.Check if Word Can Be Placed In Crossword/README_EN.md

Lines changed: 146 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,158 @@
6060
### **Python3**
6161

6262
```python
63-
63+
class Solution:
64+
def placeWordInCrossword(self, board: List[List[str]], word: str) -> bool:
65+
def check(i, j, a, b):
66+
x, y = i + a * k, j + b * k
67+
if 0 <= x < m and 0 <= y < n and board[x][y] != '#':
68+
return False
69+
for c in word:
70+
if (
71+
i < 0
72+
or i >= m
73+
or j < 0
74+
or j >= n
75+
or (board[i][j] != ' ' and board[i][j] != c)
76+
):
77+
return False
78+
i, j = i + a, j + b
79+
return True
80+
81+
m, n = len(board), len(board[0])
82+
k = len(word)
83+
for i in range(m):
84+
for j in range(n):
85+
left_to_right = (j == 0 or board[i][j - 1] == '#') and check(i, j, 0, 1)
86+
right_to_left = (j == n - 1 or board[i][j + 1] == '#') and check(
87+
i, j, 0, -1
88+
)
89+
up_to_down = (i == 0 or board[i - 1][j] == '#') and check(i, j, 1, 0)
90+
down_to_up = (i == m - 1 or board[i + 1][j] == '#') and check(
91+
i, j, -1, 0
92+
)
93+
if left_to_right or right_to_left or up_to_down or down_to_up:
94+
return True
95+
return False
6496
```
6597

6698
### **Java**
6799

68100
```java
101+
class Solution {
102+
private int m;
103+
private int n;
104+
private char[][] board;
105+
private String word;
106+
private int k;
107+
108+
public boolean placeWordInCrossword(char[][] board, String word) {
109+
m = board.length;
110+
n = board[0].length;
111+
this.board = board;
112+
this.word = word;
113+
k = word.length();
114+
for (int i = 0; i < m; ++i) {
115+
for (int j = 0; j < n; ++j) {
116+
boolean leftToRight = (j == 0 || board[i][j - 1] == '#') && check(i, j, 0, 1);
117+
boolean rightToLeft = (j == n - 1 || board[i][j + 1] == '#') && check(i, j, 0, -1);
118+
boolean upToDown = (i == 0 || board[i - 1][j] == '#') && check(i, j, 1, 0);
119+
boolean downToUp = (i == m - 1 || board[i + 1][j] == '#') && check(i, j, -1, 0);
120+
if (leftToRight || rightToLeft || upToDown || downToUp) {
121+
return true;
122+
}
123+
}
124+
}
125+
return false;
126+
}
127+
128+
private boolean check(int i, int j, int a, int b) {
129+
int x = i + a * k, y = j + b * k;
130+
if (x >= 0 && x < m && y >= 0 && y < n && board[x][y] != '#') {
131+
return false;
132+
}
133+
for (int p = 0; p < k; ++p) {
134+
if (i < 0 || i >= m || j < 0 || j >= n || (board[i][j] != ' ' && board[i][j] != word.charAt(p))) {
135+
return false;
136+
}
137+
i += a;
138+
j += b;
139+
}
140+
return true;
141+
}
142+
}
143+
```
144+
145+
### **C++**
146+
147+
```cpp
148+
class Solution {
149+
public:
150+
bool placeWordInCrossword(vector<vector<char>>& board, string word) {
151+
int m = board.size(), n = board[0].size();
152+
int k = word.size();
153+
auto check = [&](int i, int j, int a, int b) {
154+
int x = i + a * k, y = j + b * k;
155+
if (x >= 0 && x < m && y >= 0 && y < n && board[x][y] != '#') {
156+
return false;
157+
}
158+
for (char& c : word) {
159+
if (i < 0 || i >= m || j < 0 || j >= n || (board[i][j] != ' ' && board[i][j] != c)) {
160+
return false;
161+
}
162+
i += a;
163+
j += b;
164+
}
165+
return true;
166+
};
167+
for (int i = 0; i < m; ++i) {
168+
for (int j = 0; j < n; ++j) {
169+
bool leftToRight = (j == 0 || board[i][j - 1] == '#') && check(i, j, 0, 1);
170+
bool rightToLeft = (j == n - 1 || board[i][j + 1] == '#') && check(i, j, 0, -1);
171+
bool upToDown = (i == 0 || board[i - 1][j] == '#') && check(i, j, 1, 0);
172+
bool downToUp = (i == m - 1 || board[i + 1][j] == '#') && check(i, j, -1, 0);
173+
if (leftToRight || rightToLeft || upToDown || downToUp) {
174+
return true;
175+
}
176+
}
177+
}
178+
return false;
179+
}
180+
};
181+
```
69182
183+
### **Go**
184+
185+
```go
186+
func placeWordInCrossword(board [][]byte, word string) bool {
187+
m, n := len(board), len(board[0])
188+
k := len(word)
189+
check := func(i, j, a, b int) bool {
190+
x, y := i+a*k, j+b*k
191+
if x >= 0 && x < m && y >= 0 && y < n && board[x][y] != '#' {
192+
return false
193+
}
194+
for _, c := range word {
195+
if i < 0 || i >= m || j < 0 || j >= n || (board[i][j] != ' ' && board[i][j] != byte(c)) {
196+
return false
197+
}
198+
i, j = i+a, j+b
199+
}
200+
return true
201+
}
202+
for i := range board {
203+
for j := range board[i] {
204+
leftToRight := (j == 0 || board[i][j-1] == '#') && check(i, j, 0, 1)
205+
rightToLeft := (j == n-1 || board[i][j+1] == '#') && check(i, j, 0, -1)
206+
upToDown := (i == 0 || board[i-1][j] == '#') && check(i, j, 1, 0)
207+
downToUp := (i == m-1 || board[i+1][j] == '#') && check(i, j, -1, 0)
208+
if leftToRight || rightToLeft || upToDown || downToUp {
209+
return true
210+
}
211+
}
212+
}
213+
return false
214+
}
70215
```
71216

72217
### **...**
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
class Solution {
2+
public:
3+
bool placeWordInCrossword(vector<vector<char>>& board, string word) {
4+
int m = board.size(), n = board[0].size();
5+
int k = word.size();
6+
auto check = [&](int i, int j, int a, int b) {
7+
int x = i + a * k, y = j + b * k;
8+
if (x >= 0 && x < m && y >= 0 && y < n && board[x][y] != '#') {
9+
return false;
10+
}
11+
for (char& c : word) {
12+
if (i < 0 || i >= m || j < 0 || j >= n || (board[i][j] != ' ' && board[i][j] != c)) {
13+
return false;
14+
}
15+
i += a;
16+
j += b;
17+
}
18+
return true;
19+
};
20+
for (int i = 0; i < m; ++i) {
21+
for (int j = 0; j < n; ++j) {
22+
bool leftToRight = (j == 0 || board[i][j - 1] == '#') && check(i, j, 0, 1);
23+
bool rightToLeft = (j == n - 1 || board[i][j + 1] == '#') && check(i, j, 0, -1);
24+
bool upToDown = (i == 0 || board[i - 1][j] == '#') && check(i, j, 1, 0);
25+
bool downToUp = (i == m - 1 || board[i + 1][j] == '#') && check(i, j, -1, 0);
26+
if (leftToRight || rightToLeft || upToDown || downToUp) {
27+
return true;
28+
}
29+
}
30+
}
31+
return false;
32+
}
33+
};

0 commit comments

Comments
 (0)