算法---LeetCode 79. 单词搜索

1. 题目

原题链接

给定一个二维网格和一个单词,找出该单词是否存在于网格中。
单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。

示例:
board =
[
[‘A’,‘B’,‘C’,‘E’],
[‘S’,‘F’,‘C’,‘S’],
[‘A’,‘D’,‘E’,‘E’]
]
给定 word = “ABCCED”, 返回 true
给定 word = “SEE”, 返回 true
给定 word = “ABCB”, 返回 false

提示:

board 和 word 中只包含大写和小写英文字母。
1 <= board.length <= 200
1 <= board[i].length <= 200
1 <= word.length <= 10^3

Related Topics 数组 回溯算法
👍 759 👎 0

2. 题解

2.1 解法1: dfs回溯法

dfs方法作用:
判断以网格的 (i, j)位置出发,能否搜索到单词 word[k…],其中word[k…] 表示字符串 word 从第 k个字符开始的后缀子串。
如果能搜索到,则返回 true,反之返回 false。

pos 为当前遍历到的单词位置

    class Solution {
        int m, n;
        char[][] board;
        char[] word;
        boolean[][] mark;

        public boolean exist(char[][] board, String word) {
            this.m = board.length;
            this.n = board[0].length;
            this.board = board;
            this.word = word.toCharArray();
            this.mark = new boolean[m][n];
            for (int i = 0; i < m; i++) {
                for (int j = 0; j < n; j++) {
                    if (dfs(0, i, j)) return true;
                }
            }
            return false;
        }

        private boolean dfs(int pos, int i, int j) {
            if (i < 0 || i >= m || j < 0 || j >= n || mark[i][j]) return false;
            if (board[i][j] != word[pos]) return false;
            if (pos == word.length - 1) return true;
            mark[i][j] = true;
            if (dfs(pos + 1, i + 1, j)) return true;
            if (dfs(pos + 1, i - 1, j)) return true;
            if (dfs(pos + 1, i, j + 1)) return true;
            if (dfs(pos + 1, i, j - 1)) return true;
            mark[i][j] = false;
            return false;
        }
    }

写法2:

    class Solution {
        char[][] board;
        char[] wordArray;
        int m;
        int n;
        boolean[][] visited;
        int[][] direction = new int[][]{{-1, 0}, {0, -1}, {1, 0}, {0, 1}};

        public boolean exist(char[][] board, String word) {
            this.board = board;
            this.m = board.length;
            this.n = board[0].length;
            this.visited = new boolean[m][n];
            this.wordArray = word.toCharArray();
            for (int i = 0; i < m; i++) {
                for (int j = 0; j < n; j++) {
                    if (dfs(i, j, 0)) {
                        return true;
                    }
                }
            }
            return false;
        }

        public boolean dfs(int i, int j, int index) {
            if (index == wordArray.length - 1 && wordArray[index] == board[i][j]) {
                return true;
            }
            // 注意 判断条件和下标等 细节
            if (index < wordArray.length - 1 && wordArray[index] == board[i][j]) {
                visited[i][j] = true;
                for (int k = 0; k < 4; k++) {
                    int newX = i + direction[k][0];
                    int newY = j + direction[k][1];
                    if (inArea(newX, newY) && !visited[newX][newY]) {
                        if (dfs(newX, newY, index + 1)) {
                            return true;
                        }
                    }
                }
                visited[i][j] = false;
            }
            return false;
        }

        public boolean inArea(int x, int y) {
            return x < m && x >= 0 && y < n && y >= 0;
        }

    }

参考:
官方题解
在二维平面上使用回溯法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值