力扣 79 单词搜索

本文介绍了一种在二维网格中查找指定单词的算法实现。单词由相邻单元格的字母构成,相邻指水平或垂直相邻,且同一单元格的字母不可重复使用。通过递归深度优先搜索,检查每个可能的路径,直到找到单词或确认不存在。

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

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

代码:

class Solution {
    public boolean exist(char[][] board, String word) {
        int h = board.length, w = board[0].length;
        boolean[][] visited = new boolean[h][w];
        for (int i = 0; i < h; i++) {
            for (int j = 0; j < w; j++) {
                boolean flag = check(board, visited, i, j, word, 0);
                if (flag) {
                    return true;
                }
            }
        }
        return false;
    }

    public boolean check(char[][] board, boolean[][] visited, int i, int j, String s, int k) {
        if (board[i][j] != s.charAt(k)) {
            return false;
        } else if (k == s.length() - 1) {
            return true;
        }
        visited[i][j] = true;
        int[][] directions = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
        boolean result = false;
        for (int[] dir : directions) {
            int newi = i + dir[0], newj = j + dir[1];
            if (newi >= 0 && newi < board.length && newj >= 0 && newj < board[0].length) {
                if (!visited[newi][newj]) {
                    boolean flag = check(board, visited, newi, newj, s, k + 1);
                    if (flag) {
                        result = true;
                        break;
                    }
                }
            }
        }
        visited[i][j] = false;
        return result;
    }
}

### LeetCode 单词搜索问题的解题思路 #### 问题描述 LeetCode 上的“单词搜索”问题是经典的回溯算法应用之一。该问题的核心在于在一个二维字符数组 `board` 中找到是否存在一条路径能够拼接成目标字符串 `word`。路径的方向可以是上下左右四个方向,且不允许重复访问同一个单元格。 --- #### 基本思路 解决此问题的关键是从二维网格中的每一个可能起点出发,尝试通过深度优先搜索(DFS)来构建目标单词。具体实现过程中需要注意以下几个方面: 1. **边界条件处理** 需要在 DFS 开始之前判断一些简单的剪枝条件,比如如果当前字符不等于目标单词的第一个字符,则可以直接跳过这个位置作为起始点[^1]。 2. **标记已访问节点** 使用一个布尔型矩阵或者原地修改的方式记录已经访问过的单元格,防止在同一次搜索中多次访问同一单元格。 3. **递归终止条件** 当成功匹配到整个单词时返回真;当无法继续扩展路径或超出边界时停止递归并返回假。 4. **多方向探索** 对于每个有效的位置 `(i, j)` ,分别向其四周未越界的邻居节点发起新的递归调用,直到完成整条路径的验证。 5. **时间复杂度分析** 整体的时间复杂度为 \(O(m \times n \times 3^L)\),其中 \(m\) 和 \(n\) 表示二维网格的高度和宽度,\(L\) 则表示待查找单词的最大长度。这是因为对于除第一个分支外其余三个方向的选择构成了指数级增长的可能性空间[^3]。 6. **优化策略** - 如果发现某个前缀不存在于任何候选答案之中,那么应该尽早结束这条线路的进一步考察。 - 可以利用字典树结构预处理输入列表从而加速多个模式串的同时查询效率[^2]。 --- #### Python 实现代码 下面提供了一个基于上述逻辑的具体解决方案: ```python def exist(board, word): rows, cols = len(board), len(board[0]) def dfs(r, c, index): if index == len(word): # 已经找到了完整的单词 return True if r < 0 or c < 0 or r >= rows or c >= cols: # 越界情况 return False if board[r][c] != word[index]: # 字符不匹配 return False temp = board[r][c] board[r][c] = '#' # 标记当前位置已被占用 found = ( dfs(r + 1, c, index + 1) or dfs(r - 1, c, index + 1) or dfs(r, c + 1, index + 1) or dfs(r, c - 1, index + 1) ) board[r][c] = temp # 还原状态以便后续操作 return found for i in range(rows): for j in range(cols): if dfs(i, j, 0): # 尝试从每个位置开始寻找 return True return False ``` --- #### 总结 通过对 “单词搜索” 问题的理解可以看出它不仅考验了我们对基础数据结构掌握程度如何,同时也锻炼了解决实际编程挑战的能力。采用合适的剪枝技术以及合理的存储管理手段可以帮助提高程序运行性能[^4]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值