Welcome to Subscribe On Youtube
Question
Formatted question description: https://leetcode.ca/all/79.html
Given an m x n
grid of characters board
and a string word
, return true
if word
exists in the grid.
The word can be constructed from letters of sequentially adjacent cells, where adjacent cells are horizontally or vertically neighboring. The same letter cell may not be used more than once.
Example 1:
Input: board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCCED" Output: true
Example 2:
Input: board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "SEE" Output: true
Example 3:
Input: board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCB" Output: false
Constraints:
m == board.length
n = board[i].length
1 <= m, n <= 6
1 <= word.length <= 15
board
andword
consists of only lowercase and uppercase English letters.
Follow up: Could you use search pruning to make your solution faster with a larger board
?
Algorithm
This question is a typical application of depth-first traversal DFS. The original two-dimensional array is like a maze. You can walk in four directions. We use each number in the two-dimensional array as a starting point to match a given string. We also need a visited array of the same size as the original array, which is of bool type to record whether the current location has been visited, because the topic requires that a cell can only be visited once.
If the current character of the two-dimensional array board is equal to the character corresponding to the target string word, then the DFS recursive function is called respectively for the four adjacent characters of the upper, lower, left, and right
directions. As long as one of them returns true, then the corresponding string can be found. Otherwise it can’t be found
Code
-
public class Word_Search { public class Solution { int m; int n; public boolean exist(char[][] board, String word) { m = board.length; n = board[0].length; boolean result = false; for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { if (dfs(board, word, i, j, 0)) { return true; } } } return result; } public boolean dfs(char[][] board, String word, int i, int j, int wordPos) { if (wordPos == word.length()) { return true; } // @note: here, return check can remove the boundary check in each recursion, nice! if (i < 0 || j < 0 || i >= m || j >= n || board[i][j] != word.charAt(wordPos)) { return false; } char temp = board[i][j]; board[i][j] = '#'; boolean result = ( dfs(board, word, i - 1, j, wordPos + 1) || dfs(board, word, i + 1, j, wordPos + 1) || dfs(board, word, i, j - 1, wordPos + 1) || dfs(board, word, i, j + 1, wordPos + 1)); // restore from `#` board[i][j] = temp; return result; } } } ############ class Solution { public boolean exist(char[][] board, String word) { int m = board.length; int n = board[0].length; for (int i = 0; i < m; ++i) { for (int j = 0; j < n; ++j) { if (dfs(i, j, 0, m, n, board, word)) { return true; } } } return false; } private boolean dfs(int i, int j, int cur, int m, int n, char[][] board, String word) { if (cur == word.length()) { return true; } if (i < 0 || i >= m || j < 0 || j >= n || board[i][j] != word.charAt(cur)) { return false; } board[i][j] += 256; int[] dirs = {-1, 0, 1, 0, -1}; for (int k = 0; k < 4; ++k) { int x = i + dirs[k]; int y = j + dirs[k + 1]; if (dfs(x, y, cur + 1, m, n, board, word)) { return true; } } board[i][j] -= 256; return false; } }
-
// OJ: https://leetcode.com/problems/word-search/ // Time: O(MN * 4^K) // Space: O(K) class Solution { public: bool exist(vector<vector<char>>& A, string s) { int M = A.size(), N = A[0].size(), dirs[4][2] = { {0,1},{0,-1},{1,0},{-1,0} }; function<bool(int, int, int)> dfs = [&](int x, int y, int i) { if (x < 0 || x >= M || y < 0 || y >= N || A[x][y] != s[i]) return false; if (i + 1 == s.size()) return true; char c = A[x][y]; A[x][y] = 0; for (auto &[dx, dy] : dirs) { if (dfs(x + dx, y + dy, i + 1)) return true; } A[x][y] = c; return false; }; for (int i = 0; i < M; ++i) { for (int j = 0; j < N; ++j) { if (dfs(i, j, 0)) return true; } } return false; } };
-
class Solution: def exist(self, board: List[List[str]], word: str) -> bool: def dfs(i, j, cur): # cur: current char count if cur == len(word): return True if ( i < 0 or i >= m or j < 0 or j >= n or board[i][j] == '0' or word[cur] != board[i][j] ): return False t = board[i][j] board[i][j] = '0' # mark as visited for a, b in [[0, 1], [0, -1], [-1, 0], [1, 0]]: x, y = i + a, j + b if dfs(x, y, cur + 1): return True board[i][j] = t return False m, n = len(board), len(board[0]) return any(dfs(i, j, 0) for i in range(m) for j in range(n)) ############ class Solution: # @param board, a list of lists of 1 length string # @param word, a string # @return a boolean def exist(self, board, word): # write your code here if word == "": return True if len(board) == 0: return False visited = [[0] * len(board[0]) for i in range(0, len(board))] directions = [(-1, 0), (1, 0), (0, -1), (0, 1)] def dfs(i, j, board, visited, word, index): if word[index] != board[i][j]: return False if len(word) - 1 == index: return True for direction in directions: ni, nj = i + direction[0], j + direction[1] if ni >= 0 and ni < len(board) and nj >= 0 and nj < len(board[0]): if visited[ni][nj] == 0: visited[ni][nj] = 1 if dfs(ni, nj, board, visited, word, index + 1): return True visited[ni][nj] = 0 return False for i in range(0, len(board)): for j in range(0, len(board[0])): visited[i][j] = 1 if dfs(i, j, board, visited, word, 0): return True visited[i][j] = 0 return False
-
func exist(board [][]byte, word string) bool { m, n := len(board), len(board[0]) var dfs func(i, j, cur int) bool dfs = func(i, j, cur int) bool { if cur == len(word) { return true } if i < 0 || i >= m || j < 0 || j >= n || board[i][j] != word[cur] { return false } t := board[i][j] board[i][j] = '0' dirs := []int{-1, 0, 1, 0, -1} for k := 0; k < 4; k++ { x, y := i+dirs[k], j+dirs[k+1] if dfs(x, y, cur+1) { return true } } board[i][j] = t return false } for i := 0; i < m; i++ { for j := 0; j < n; j++ { if dfs(i, j, 0) { return true } } } return false }
-
function exist(board: string[][], word: string): boolean { let m = board.length, n = board[0].length; let visited = Array.from({ length: m }, v => new Array(n).fill(false)); for (let i = 0; i < m; ++i) { for (let j = 0; j < n; ++j) { if (dfs(board, word, i, j, 0, visited)) { return true; } } } return false; } function dfs( board: string[][], word: string, i: number, j: number, depth: number, visited: boolean[][], ): boolean { let m = board.length, n = board[0].length; if (i < 0 || i > m - 1 || j < 0 || j > n - 1 || visited[i][j]) { return false; } if (board[i][j] != word.charAt(depth)) { return false; } if (depth == word.length - 1) { return true; } visited[i][j] = true; ++depth; let res = false; for (let [dx, dy] of [ [0, 1], [0, -1], [1, 0], [-1, 0], ]) { let x = i + dx, y = j + dy; res = res || dfs(board, word, x, y, depth, visited); } visited[i][j] = false; return res; }
-
public class Solution { public bool Exist(char[][] board, string word) { var lenI = board.Length; var lenJ = lenI == 0 ? 0 : board[0].Length; var visited = new bool[lenI, lenJ]; for (var i = 0; i < lenI; ++i) { for (var j = 0; j < lenJ; ++j) { if (Search(board, visited, word, lenI, lenJ, i, j, 0)) { return true; } } } return false; } private int[,] paths = new int[4,2] { { -1, 0 }, { 1, 0 }, { 0, -1 }, { 0, 1 } }; private bool Search(char[][] board, bool[,] visited, string word, int lenI, int lenJ, int i, int j, int p) { if (p == word.Length) { return true; } if (i < 0 || i >= lenI || j < 0 || j >= lenJ) return false; if (visited[i, j] || word[p] != board[i][j]) return false; visited[i, j] = true; for (var k = 0; k < 4; ++k) { if (Search(board, visited, word, lenI, lenJ, i + paths[k, 0], j + paths[k, 1], p + 1)) return true; } visited[i, j] = false; return false; } }
-
impl Solution { fn dfs( i: usize, j: usize, c: usize, word: &[u8], board: &Vec<Vec<char>>, vis: &mut Vec<Vec<bool>>, ) -> bool { if board[i][j] as u8 != word[c] { return false; } if c == word.len() - 1 { return true; } vis[i][j] = true; let dirs = [[-1, 0], [0, -1], [1, 0], [0, 1]]; for [x, y] in dirs.into_iter() { // 索引合法性审核 let i = x + i as i32; let j = y + j as i32; if i < 0 || i == board.len() as i32 || j < 0 || j == board[0].len() as i32 { continue; } let (i, j) = (i as usize, j as usize); if !vis[i][j] && Self::dfs(i, j, c + 1, word, board, vis) { return true; } } vis[i][j] = false; false } pub fn exist(board: Vec<Vec<char>>, word: String) -> bool { let m = board.len(); let n = board[0].len(); let word = word.as_bytes(); let mut vis = vec![vec![false; n]; m]; for i in 0..m { for j in 0..n { if Self::dfs(i, j, 0, word, &board, &mut vis) { return true; } } } false } }