LeetCode笔记——79单词搜索

题目:

给定一个二维网格和一个单词,找出该单词是否存在于网格中。

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

示例:

board =
[
  ['A','B','C','E'],
  ['S','F','C','S'],
  ['A','D','E','E']
]

给定 word = "ABCCED", 返回 true.
给定 word = "SEE", 返回 true.
给定 word = "ABCB", 返回 false.

思路:直接看了大神们的思路和代码,原文链接:https://blog.csdn.net/DERRANTCM/article/details/47248121

整个代码使用了回溯的思想,就是迭代加上循环。需要的数据结构包括一个记录是否访问过的数组,一个记录检查到给定字符的哪个位置的数组。首先遍历数组中的每一个元素,对于一个元素检查该元素是否合法,即行列号是否合法,是否被访问过,是否与对应word中的值相等,若这一切条件均满足,则递归调用函数检查上下左右的位置;如果搜索的位置等于字串的长度,说明已经找到找到匹配的了, 如果没有找到路径(hasPath=false)就回溯。

代码:

class Solution {
   
    public boolean exist(char[][] board, String word) { // 【注意我们假定输入的参数都是合法】
        // 访问标记矩阵,初始值默认会设置为false
        boolean[][] visited = new boolean[board.length][board[0].length];
        // 以每一个位置为起点进行搜索,找到一个路径就停止
        for (int i = 0; i < board.length; i++) {
            for (int j = 0; j < board[0].length; j++) {
                if (search(board, visited, i, j, word, new int[]{0})) {
                    return true;
                }
            }
        }
        return false;
    }
    /**
     * @param board   字符矩阵
     * @param visited 访问标记矩阵
     * @param row     访问的行号
     * @param col     访问的列号
     * @param word    匹配的字符串
     * @param idx     匹配的位置,取数组是更新后的值可以被其它引用所见
     * @return
     */
    private boolean search(char[][] board, boolean[][] visited, int row, int col, String word, int[] idx) {
        // 如果搜索的位置等于字串的长度,说明已经找到找到匹配的了
        if (idx[0] == word.length()) {
            return true;
        }
        boolean hasPath = false;
        // 当前位置合法
        if (check(board, visited, row, col, word, idx[0])) {
            // 标记位置被访问过
            visited[row][col] = true;
            idx[0]++;
            // 对上,右,下,左四个方向进行搜索
            hasPath = search(board, visited, row - 1, col, word, idx ) // 上
                || search(board, visited, row, col + 1, word, idx) // 右
                || search(board, visited, row + 1, col, word, idx) // 下
                || search(board, visited, row, col - 1, word, idx); // 左
            // 如果没有找到路径就回溯
            if (!hasPath) {
                visited[row][col] = false;
                idx[0]--;
            }
        }
        return hasPath;
    }
    /**
     * 判定访问的位置是否合法
     *
     * @param board   字符矩阵
     * @param visited 访问标记矩阵
     * @param row     访问的行号
     * @param col     访问的列号
     * @param word    匹配的字符串
     * @param idx     匹配的位置
     * @return
     */
    public boolean check(char[][] board, boolean[][] visited, int row, int col, String word, int idx) {
        return row >= 0 && row < board.length // 行号合法
            && col >= 0 && col < board[0].length // 列号合法
            && !visited[row][col] // 没有被访问过
            && board[row][col] == word.charAt(idx);
        // 字符相等
    }
}

执行最快的的代码:

思路和上面的相同。

class Solution {
     int m;
    int n;

    public boolean exist(char[][] board, String word) {
        if (null == board || word == null || word.isEmpty()) {
            return false;
        }

        boolean[][] used = new boolean[board.length][board[0].length];


        m = board.length;
        n = board[0].length;

        char[] charArray = word.toCharArray();

        for(int i=0; i<m; i++) {
            for(int j=0; j<n;j++) {
                if (exist(board, used, charArray, i, j, 0)) {
                    return true;
                }
            }
        }

        return false;

    }

    private boolean exist(char[][] board, boolean[][] mem, char[] charArray, int i, int j, int index) {
        if (index == charArray.length) {
            return true;
        }

        if (i >= m || i < 0) {
            return false;
        }

        if (j >= n || j < 0) {
            return false;
        }


        if (mem[i][j] || board[i][j] != charArray[index]) {
            return false;
        }

        mem[i][j] = true;
        // up -> right -> down -> left
        boolean found = exist(board, mem, charArray, i - 1, j, index + 1)
                || exist(board, mem, charArray, i, j + 1, index + 1)
                || exist(board, mem, charArray, i + 1, j, index + 1)
                || exist(board, mem, charArray, i, j - 1, index + 1);


        // recover
        if (!found) mem[i][j] = false;


        return found;
    }
}

猜你喜欢

转载自blog.csdn.net/chenxy132/article/details/83303225