79. Word Search -Medium

Question

Given a 2D board and a word, find if the word exists in the grid.

The word can be constructed from letters of sequentially adjacent cell, where “adjacent” cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once.

给出一个二维的模板网格和一个单词,请你找出这个单词是否在模板中存在。在搜索过程中,这个单词可以通过相邻网格(相邻的垂直水平网格都可以)来构造。同一网格的字母只能使用一次

Example

Given board =

[
[‘A’,’B’,’C’,’E’],
[‘S’,’F’,’C’,’S’],
[‘A’,’D’,’E’,’E’]
]

word = “ABCCED”, -> returns true,
word = “SEE”, -> returns true,
word = “ABCB”, -> returns false.

Solution

  • 回溯解。我们需要分别判断以网格的任意一点作为起始点进行搜索能否得到该word单词,因为同一个网格不能走两次,所以在搜索过程中需要标记已搜索过的网格,为了不额外增加空间,我们可以改变网格元素内容代表已搜索过。

    public class Solution {
        public boolean exist(char[][] board, String word) {
            // 分别以board的不同元素作为搜索起点进行搜索
            for(int i = 0;i < board.length; i++){
                for(int j = 0;j < board[i].length; j++){
                    if(backtracking(board, word, i, j, 0)) return true;
                }
            }
            return false;
        }
    
        /**
         * 思路:检测以board[index_x][index_y]为头的序列是否能够搜索到word单词。每次检测当前board元素是否能够匹配word的当前元素,
         *       如果能够能够匹配,则递归进行下一个字母的搜索,否则跳过
         * @param board:保存字母的模板
         * @param word:要搜索的单词
         * @param index_x:board的x轴索引
         * @param index_y:board的y轴索引
         * @param index_w:要搜索的单词的当前字符索引
         * @return:是否能够搜索到word单词
         */
        public boolean backtracking(char[][] board, String word, int index_x, int index_y, int index_w){
            // 如果每个字母都已经被搜索到了,则返回true
            if(index_w == word.length()) return true;
    
            // 如果搜索点走出了board边界则回退
            if(index_x < 0 || index_y < 0 || index_x >= board.length || index_y >= board[0].length) return false;
    
            // 如果board当前元素不能搜索到该字母,则回退
            if(board[index_x][index_y] != word.charAt(index_w)) return false;
    
            // 到了这里代表当前字母已经搜索到了,接下去搜索下一个字母
            // 保存当前board元素的值
            char temp = board[index_x][index_y];
            // 将该元素改为"*"代表该位置已经搜索过了
            board[index_x][index_y] = '*';
            // 分别向4个方向走,只要有一个方向能够搜索到下个字母就返回true
            boolean isexist = backtracking(board, word, index_x + 1, index_y, index_w + 1) ||
                    backtracking(board, word, index_x, index_y + 1, index_w + 1) ||
                    backtracking(board, word, index_x - 1, index_y, index_w + 1) ||
                    backtracking(board, word, index_x, index_y - 1, index_w + 1);
            // 每次搜索完都将原来的值恢复以便下一次搜索
            board[index_x][index_y] = temp;
            return isexist;
        }
    }

你可能感兴趣的:(LeetCode-回溯)