题目描述
给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。
单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。
示例 1:
输入:board = [[“A”,”B”,”C”,”E”],[“S”,”F”,”C”,”S”],[“A”,”D”,”E”,”E”]], word = “ABCCED” 
输出:true
示例 2:
输入:board = [[“A”,”B”,”C”,”E”],[“S”,”F”,”C”,”S”],[“A”,”D”,”E”,”E”]], word = “SEE” 
输出:true
示例 3:
输入:board = [[“A”,”B”,”C”,”E”],[“S”,”F”,”C”,”S”],[“A”,”D”,”E”,”E”]], word = “ABCB” 
输出:false
提示:
- m == board.length
 - n = board[i].length
 - 1 <= m, n <= 6
 - 1 <= word.length <= 15
 - board 和 word 仅由大小写英文字母组成
 
进阶:你可以使用搜索剪枝的技术来优化解决方案,使其在 board 更大的情况下可以更快解决问题?
个人解法
Javascript
回溯
/** @lc app=leetcode.cn id=79 lang=javascript** [79] 单词搜索*/// @lc code=startconst dfs = function (board, i, j, target, m, n, res) {if (!target.length) {return true;}let str = target[0];const up = i > 0 ? board[i - 1][j] : null;const down = i < m - 1 ? board[i + 1][j] : null;const left = j > 0 ? board[i][j - 1] : null;const right = j < n - 1 ? board[i][j + 1] : null;let flag = false;if (res.indexOf(`${i - 1},${j}`) === -1 && up === str) {flag = dfs(board, i - 1, j, target.substring(1), m, n, [...res, `${i - 1},${j}`]) || flag;if (flag) {return true;}}if (res.indexOf(`${i + 1},${j}`) === -1 && down === str) {flag = dfs(board, i + 1, j, target.substring(1), m, n, [...res, `${i + 1},${j}`]) || flag;if (flag) {return true;}}if (res.indexOf(`${i},${j - 1}`) === -1 && left === str) {flag = dfs(board, i, j - 1, target.substring(1), m, n, [...res, `${i},${j - 1}`]) || flag;if (flag) {return true;}}if (res.indexOf(`${i},${j + 1}`) === -1 && right === str) {flag = dfs(board, i, j + 1, target.substring(1), m, n, [...res, `${i},${j + 1}`]) || flag;if (flag) {return true;}}return flag;}/*** @param {character[][]} board* @param {string} word* @return {boolean}*/var exist = function (board, word) {const m = board.length;const n = board[0].length;const res = [];const result = [];for (let i = 0; i < m; i++) {for (let j = 0; j < n; j++) {if (board[i][j] === word[0]) {res.push([i, j]);}}}const len = res.length;if (len === 0) {return false;}for (let i = 0; i < len; i++) {res[i] = dfs(board, res[i][0], res[i][1], word.substring(1), m, n, [`${res[i][0]},${res[i][1]}`]);if (res[i]) {return true;}}return res.indexOf(true) > -1;};// @lc code=end
Java
回溯
class Solution {public boolean exist(char[][] board, String word) {int w=board[0].length,h=board.length;boolean[][] flag=new boolean[h][w];for (int i=0;i<h;i++){for (int j=0;j<w;j++){boolean result=check(board,word,flag,i,j,0);if (result==true){return true;}}}return false;}public boolean check(char[][] board,String word,boolean[][] flag,int i,int j,int k){//如果当前字符和位置k的目标字符不相等,直接返回falseif (board[i][j]!=word.charAt(k)){return false;//如果最后一位字符对应字符也找到了,说明字符串存在,返回true}else if (k==word.length()-1){return true;}//当前字符和位置k目标字符对应,寻找下一个字符,标记当前字符已访问flag[i][j]=true;boolean result=false;//上下左右int[][] nums=new int[][]{{-1,0},{1,0},{0,-1},{0,1}};for (int[] n:nums){int newI=i+n[0],newJ=j+n[1];//判断有没有越界if (newI>=0&&newJ>=0&&newI< board.length&&newJ<board[0].length){if (flag[newI][newJ]==false){boolean f=check(board, word, flag, newI, newJ, k+1);if (f==true){result=true;break;}}}}//复原当前字符状态,不阻碍下一次寻找flag[i][j]=false;return result;}}
其他解法
Java
Javascript
DFS优化
/** @lc app=leetcode.cn id=79 lang=javascript** [79] 单词搜索*/// @lc code=start/*** @param {character[][]} board* @param {string} word* @return {boolean}*/var exist = function (board, word) {const h = board.length, w = board[0].length;const directions = [[0, 1], [0, -1], [1, 0], [-1, 0]];const visited = new Array(h);for (let i = 0; i < visited.length; ++i) {visited[i] = new Array(w).fill(false);}const check = (i, j, s, k) => {if (board[i][j] != s.charAt(k)) {return false;} else if (k == s.length - 1) {return true;}visited[i][j] = true;let result = false;for (const [dx, dy] of directions) {let newi = i + dx, newj = j + dy;if (newi >= 0 && newi < h && newj >= 0 && newj < w) {if (!visited[newi][newj]) {const flag = check(newi, newj, s, k + 1);if (flag) {result = true;break;}}}}visited[i][j] = false;return result;}for (let i = 0; i < h; i++) {for (let j = 0; j < w; j++) {const flag = check(i, j, word, 0);if (flag) {return true;}}}return false;};// @lc code=end
