Skip to content

Commit 0255705

Browse files
authored
Add WordSearch (TheAlgorithms#4189)
1 parent de2696d commit 0255705

2 files changed

Lines changed: 111 additions & 0 deletions

File tree

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package com.thealgorithms.backtracking;
2+
3+
4+
/*
5+
Word Search Problem (https://en.wikipedia.org/wiki/Word_search)
6+
7+
Given an m x n grid of characters board and a string word, return true if word exists in the grid.
8+
9+
The word can be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or
10+
vertically neighboring. The same letter cell may not be used more than once.
11+
12+
For example,
13+
Given board =
14+
15+
[
16+
['A','B','C','E'],
17+
['S','F','C','S'],
18+
['A','D','E','E']
19+
]
20+
word = "ABCCED", -> returns true,
21+
word = "SEE", -> returns true,
22+
word = "ABCB", -> returns false.
23+
*/
24+
25+
/*
26+
Solution
27+
Depth First Search in matrix (as multiple sources possible) with backtracking
28+
like finding cycle in a directed graph. Maintain a record of path
29+
30+
Tx = O(m * n * 3^L): for each cell, we look at 3 options (not 4 as that one will be visited), we do it L times
31+
Sx = O(L) : stack size is max L
32+
*/
33+
34+
public class WordSearch {
35+
private final int[] dx = {0, 0, 1, -1};
36+
private final int[] dy = {1, -1, 0, 0};
37+
private boolean[][] visited;
38+
private char[][] board;
39+
private String word;
40+
41+
private boolean isValid(int x, int y) {
42+
return x >= 0 && x < board.length && y >= 0 && y < board[0].length;
43+
}
44+
45+
private boolean doDFS(int x, int y, int nextIdx) {
46+
visited[x][y] = true;
47+
if (nextIdx == word.length()) {
48+
return true;
49+
}
50+
for (int i = 0; i < 4; ++i) {
51+
int xi = x + dx[i];
52+
int yi = y + dy[i];
53+
if (isValid(xi, yi) && board[xi][yi] == word.charAt(nextIdx) && !visited[xi][yi]) {
54+
boolean exists = doDFS(xi, yi, nextIdx + 1);
55+
if (exists)
56+
return true;
57+
}
58+
}
59+
visited[x][y] = false;
60+
return false;
61+
}
62+
63+
public boolean exist(char[][] board, String word) {
64+
this.board = board;
65+
this.word = word;
66+
for (int i = 0; i < board.length; ++i) {
67+
for (int j = 0; j < board[0].length; ++j) {
68+
if (board[i][j] == word.charAt(0)) {
69+
visited = new boolean[board.length][board[0].length];
70+
boolean exists = doDFS(i, j, 1);
71+
if (exists)
72+
return true;
73+
}
74+
}
75+
}
76+
return false;
77+
}
78+
}
79+
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package com.thealgorithms.backtracking;
2+
3+
import static org.junit.jupiter.api.Assertions.assertTrue;
4+
5+
import org.junit.jupiter.api.Assertions;
6+
import org.junit.jupiter.api.Test;
7+
8+
public class WordSearchTest {
9+
@Test
10+
void test1() {
11+
WordSearch ws = new WordSearch();
12+
char[][] board = {{'A','B','C','E'},{'S','F','C','S'},{'A','D','E','E'}};
13+
String word = "ABCCED";
14+
assertTrue(ws.exist(board, word));
15+
}
16+
17+
@Test
18+
void test2() {
19+
WordSearch ws = new WordSearch();
20+
char[][] board = {{'A','B','C','E'},{'S','F','C','S'},{'A','D','E','E'}};
21+
String word = "SEE";
22+
assertTrue(ws.exist(board, word));
23+
}
24+
25+
@Test
26+
void test3() {
27+
WordSearch ws = new WordSearch();
28+
char[][] board = {{'A','B','C','E'},{'S','F','C','S'},{'A','D','E','E'}};
29+
String word = "ABCB";
30+
Assertions.assertFalse(ws.exist(board, word));
31+
}
32+
}

0 commit comments

Comments
 (0)