前言
大三下学期了,既然已经准备工作的话,就要开始自己的刷题之旅了。目前自己正在看剑指offer里面的题目。已经刷了将近30道题,但是现在再去看前几天自己做出来的题依然不能完整的写出来。所以我觉得应该停下来去复习一下前面的题目,整理一下做题的套路。所以把自己的刷题心得和思考写在这里,与大家分享。
题目描述
给定一个二维网格和一个单词,找出该单词是否存在于网格中。
单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。
难度:中等
示例:
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
解题思路
-
二维网格中查找一个单词,首先应该先在这个二维数组中找到这个单词的首字母。然后对这个二维数组进行深度优先搜索(DFS)。
-
DFS函数的参数应该是此时二维数组的坐标i,j和判断第几个单词的index。在DFS中应该首先保证i,j的值不超过二维数组的边界。否则返回false。
if(i < 0 || i >= board.length || j >= board[0].length) return false;
-
判断board[i][j]是否等于word[index]。如果等于的话就把word[index]赋值给一个变量tmp,然后把board[i][j赋值为0表示这个元素已经使用过了。然后就是对二维数组中这个元素的上下左右进行试探,看是否与word的下一个字母符合。如果匹配到就继续递归,否则就返回false。当上下左右都查找完后,应该撤销二维数组中的修改。因为一个字母只能用一次。
AC代码
/* * @lc app=leetcode.cn id=79 lang=javascript * * [79] 单词搜索 */ // @lc code=start /** * @param {character[][]} board * @param {string} word * @return {boolean} */ var exist = function (board, word) { for (let i = 0; i < board.length; i++) { for (let j = 0; j < board[0].length; j++) { //寻找第一个符合条件的字符 if (word[0] === board[i][j]) { if (dfs(i, j, 0)) { return true; } } } } return false; function dfs(i, j, index) { if (i < 0 || i >= board.length || j >= board[0].length) return false; let flag = false; if (board[i][j] === word[index]) { if (index === word.length - 1) { return true; } let tmp = board[i][j]; board[i][j] = '0'; flag = flag || dfs(i + 1, j, index + 1); flag = flag || dfs(i - 1, j, index + 1); flag = flag || dfs(i, j + 1, index + 1); flag = flag || dfs(i, j - 1, index + 1); board[i][j] = tmp; } return flag; } }; // @lc code=end board = [ ['A', 'B', 'C', 'E'], ['S', 'F', 'C', 'S'], ['A', 'D', 'E', 'E'] ] let word = "ABCCED";
总结
回溯算法就是暴力枚举,就是一个一个的去试。如果列举到一半不符合条件,就及时剪枝,并把之前做的选择撤销。同时需要递归可能出现的所有情况。也要注意结束递归的条件,本题中的结束条件分别是查完二维数组也没找到首字母,i,j小于二维数组的边界,index的值和word字符串的长度相同。
本文正在参与「掘金 2021 春招闯关活动」, 点击查看 活动详情