返回
LeetCode 79:在网格中探索单词的深度之旅
前端
2023-09-27 07:01:25
深度优先搜索:探索网格中的单词世界
导言
在计算机科学领域,算法是解决复杂问题的有力工具。LeetCode 79:单词搜索就是这样一项经典挑战,它要求我们在网格中找到一个给定单词。为了解决这个问题,我们将深入探讨一种称为深度优先搜索(DFS)的强大算法。
深度优先搜索:沿着路径前进
DFS 是一种搜索算法,它通过沿着一系列路径深入搜索网格,直到无法再前进为止。如果我们想象一下自己在一座迷宫中,DFS 就像一条沿着一条走廊探索,直到走到尽头,然后回过头来尝试另一条走廊。
回溯:纠正错误的尝试
在 DFS 过程中,我们可能会发现一条路径不通往单词的终点。这就是回溯发挥作用的地方。回溯允许我们返回到最近的有效单元格,然后从那里继续探索。这种策略确保我们不会在死胡同上浪费时间,并帮助我们找到单词存在的所有可能路径。
算法的步骤:细致入微的探索
- 初始化: 标记已访问单元格。
- 遍历网格: 检查每个单元格,寻找单词第一个字母的匹配项。
- DFS 函数: 从匹配单元格递归搜索,检查后续字母匹配情况。
- 回溯: 如果匹配失败,返回到最近的有效单元格继续探索。
- 重复: 直到单词被找到或搜索结束。
代码实现:让算法焕发生机
const exist = (board, word) => {
// 初始化已访问单元格数组
const visited = new Array(board.length).fill(false).map(() => new Array(board[0].length).fill(false));
// 遍历网格,寻找单词第一个字母的匹配项
for (let i = 0; i < board.length; i++) {
for (let j = 0; j < board[0].length; j++) {
if (board[i][j] === word[0] && dfs(i, j, 0)) {
return true;
}
}
}
// DFS 函数:从匹配单元格递归搜索
function dfs(i, j, index) {
// 边界条件:超出网格范围或已访问单元格
if (i < 0 || i >= board.length || j < 0 || j >= board[0].length || visited[i][j] || board[i][j] !== word[index]) {
return false;
}
// 找到单词最后一个字母
if (index === word.length - 1) {
return true;
}
// 标记当前单元格已访问
visited[i][j] = true;
// 递归搜索相邻单元格
const result =
dfs(i + 1, j, index + 1) ||
dfs(i - 1, j, index + 1) ||
dfs(i, j + 1, index + 1) ||
dfs(i, j - 1, index + 1);
// 搜索完成,标记当前单元格未访问
visited[i][j] = false;
// 返回搜索结果
return result;
}
// 单词未找到
return false;
};
结语:在网格中寻找单词的艺术
LeetCode 79:单词搜索是一个算法难题,需要我们应用 DFS 算法和回溯策略。通过了解这些概念并应用提供的代码示例,我们可以高效地在网格中找到单词,深入探索计算机科学的奥秘。
常见问题解答
-
DFS 和 BFS 有什么区别?
DFS 深入探索一条路径,而 BFS 广度优先搜索所有可能的路径。 -
回溯在 DFS 中的作用是什么?
回溯允许我们纠正错误的尝试并探索其他可能的路径。 -
算法时间复杂度是多少?
O(mn * 4^L),其中 m 和 n 是网格大小,L 是单词长度。 -
如何优化算法性能?
使用备忘录或剪枝技术来减少重复的搜索。 -
DFS 算法还可以应用于哪些问题?
DFS 可用于解决迷宫求解、图遍历和回路检测等问题。