给定一个 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
思路:采用深度优先和回溯的思路。是一道比较典型的回溯题。
定义了一个方向数组用于深度遍历时确定方向。
定义visited数组用于记录元素是否已经访问过。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| class Solution { private final static int[] DIRECTIONS = new int[]{-1, 0, 1, 0, -1}; private int rows; private int cols; private int len; private char[][] board; private char[] toCharArray; private boolean[][] visited; public boolean exist(char[][] board, String word) { this.rows = board.length; if (rows == 0) { return false; } this.cols = board[0].length; this.board = board; this.len = word.length(); this.visited = new boolean[rows][cols]; this.toCharArray = word.toCharArray(); for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { if (dfs(i, j, 0)) { return true; } } } return false;
}
private boolean dfs(int x, int y, int begin) { if (begin == len - 1) { return toCharArray[begin] == board[x][y]; } if (toCharArray[begin] == board[x][y]) { visited[x][y] = true; for (int i = 0; i < 4; i++) { int newX = x + DIRECTIONS[i]; int newY = y + DIRECTIONS[i + 1]; if (isInArea(newX, newY) && !visited[newX][newY]) { if (dfs(newX, newY, begin + 1)) { return true; } } } visited[x][y] = false; } return false; } private boolean isInArea(int x, int y) { return x >= 0 && x < rows && y >= 0 && y < cols; } }
|