Go Java算法之单词搜索示例详解

2022-08-23 11:00:05
目录
单词搜索算法:DFS回溯(Java)算法:DFS回溯(Go)

单词搜索

给定一个 m>

单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。

    示例 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.lengthn = board[i].length1 <= m, n <= 61 <= word.length <= 15

          board 和 word 仅由大小写英文字母组成  

          算法:DFS回溯(Java)

            以"SEE"为例,首先要选起点:遍历矩阵,找到起点S。起点可能不止一个,基于其中一个S,看看能否找出剩下的"EE"路径。下一个字符E有四个可选点:当前点的上、下、左、右。逐个尝试每一种选择。基于当前选择,为下一个字符选点,又有四种选择。每到一个点做的事情是一样的。DFS>当发现某个选择不对,不用继续选下去了,结束当前递归,考察别的选择。

            递归的关键点

              关注当前考察的点,处理它,其他丢给递归子调用去做。判断当前选择的点,本身是不是一个错的点。剩下的字符能否找到路径,交给递归子调用去做。如果当前点是错的,不用往下递归了,返回false。否则继续递归四个方向,为剩下的字符选点。

              那么,哪些情况说明这是一个错的点:

                当前的点,越出矩阵边界。当前的点,之前访问过,不满足「同一个单元格内的字母不允许被重复使用」。当前的点,不是目标点,比如你想找 E,却来到了 D。
                class Solution {
                    public boolean exist(char[][] board, String word) {
                        if (board == null || board.length == 0) {
                            return false;
                        }
                        boolean[][] visited = new boolean[board.length][board[0].length];
                        char[] chars = word.toCharArray();
                        for (int i = 0; i < board.length; i++) {
                            for (int j = 0; j < board[0].length; j++) {
                                if (existHelper(board, visited, chars, i, j, 0)) {
                                    return true;
                                }
                            }
                        }
                        return false;
                    }
                    private boolean existHelper(char[][] board, boolean[][] visited, char[] chars, int row, int column, int index) {
                        if (index == chars.length) {
                            return true;
                        }
                        int[][] direction = new int[][]{
                                {0, 1},
                                {1, 0},
                                {0, -1},
                                {-1, 0}
                        };
                        if (row >= 0 && row < board.length &&
                                column >= 0 && column < board[0].length &&
                                board[row][column] == chars[index] &&
                                !visited[row][column]) {
                            visited[row][column] = true;
                            for (int[] dir : direction) {
                                int newX = row + dir[0];
                                int newY = column + dir[1];
                                if (existHelper(board, visited, chars, newX, newY, index + 1)) {
                                    return true;
                                }
                            }
                            visited[row][column] = false;
                        }
                        return false;
                    }
                }
                

                时间复杂度:O(M*N * 3^L)

                空间复杂度:O(M*N)

                算法:DFS回溯(Go)

                思路同上

                func exist(board [][]byte, word string) bool {
                	m, n := len(board), len(board[0])
                	used := make([][]bool, m)
                	for i := 0; i < m; i++ {
                		used[i] = make([]bool, n)
                	}
                	var canFind func(r, c, i int) bool
                	canFind = func(r, c, i int) bool {
                		if i == len(word) {
                			return true
                		}
                		if r < 0 || r >= m || c < 0 || c >= n {
                			return false
                		}
                		if used[r][c] || board[r][c] != word[i] {
                			return false
                		}
                		used[r][c] = true
                		canFindRest := canFind(r+1, c, i+1) || canFind(r-1, c, i+1) ||
                			canFind(r, c+1, i+1) || canFind(r, c-1, i+1)
                		if canFindRest {
                			return true
                		} else {
                			used[r][c] = false
                			return false
                		}
                	}
                	for i := 0; i < m; i++ {
                		for j := 0; j < n; j++ {
                			if board[i][j] == word[0] && canFind(i, j, 0) {
                				return true
                			}
                		}
                	}
                	return false
                }
                

                时间复杂度:O(M*N * 3^L)

                空间复杂度:O(M*N)

                以上就是Go Java算法之单词搜索示例详解的详细内容,更多关于Go Java算法单词搜索的资料请关注易采站长站其它相关文章!