题目描述
本题难度:Medium
做题日期:2017年3月24日
本题地址: leetcode.com/problems/wo…
Given a 2D board and a word, find if the word exists in the grid.
The word can be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once.
For example,
Given board =
[
['A','B','C','E'],
['S','F','C','S'],
['A','D','E','E']
]
word = "ABCCED", -> returns true,
word = "SEE", -> returns true,
word = "ABCB", -> returns false.题目分析
题意是要求我们求一个 MxN 的二位字母表中寻找是否有满足给定单词的字母集合,限制条件是字母集合是相邻的。
这道题的特别之处在于:起始位置不确定 和 方向不定。一般的二维矩阵题目,都会给定一个起始位置,比如从左上角开始;也会限制搜索的方向,比如只能向右和向下走。
由于起始位置不定,所以我们需要轮询二维数组的所有字母。方向不定,所以我们在暴力搜索的时候,需要考虑边界限制条件。
例子分析
假设我们要在如下的二维数组中,寻找 SAD 字符串 是否符合条件。如下图一
假设我们已经确定了起始点为 S ,其位置坐标是(1, 0) 。此时,我们需要判断字符S(1,0) 周边是否有第二个字符A,此时有四个可以选择路径:
- 向右走
字符是 F(1, 1) ,不符合要求,舍弃 - 向上走
字符是 A(0, 0),符合要求 - 向下走
字符串 A(2, 0),符合要求,但由于条件 2 已经满足了,需要继续递归 - 向右走
超过了边界限制,不符合要求
在上一个步骤,我们已经确定了 SA ,接下来确定 D。 其状态如下图二所示
根据上一个步骤的分析,在 A(0, 0) 我们也有四个选择:
- 向右
B(0, 1) 不等于 D ,排除 - 向上
越界了,不符合要求,排除 - 向下
S(1, 0) 已经访问过了,也应该排除 - 向左
越界了,不符合要求,排除
在上面的分析中的第3步,我们需要排除已经访问过的字符,否则会进入死循环,这样也会重复的选择字符,不符合题目要求。
向上走的路径不符合条件后,我们需要回溯到上一个起始点,也就是 S(1, 0) 位置,重新选择路径3:向下走 。
重复最先的分析,我们可以得到 SAD 是存在的,所以结果返回 True。
小结
从上面的分析,我们在写代码的过程中,需要注意如下几点
- 注意数组越界的问题
- 如果当前位置的字母不满足条件,需要回溯到上一个起始点的字母
- 需要记录下访问的路径,防止重复访问节点
解题思路
暴力方法
用一个MxN数组 check 来标示访问路径,防止重复访问,默认值是 false。当遍历到位置(i,j) 的时候,将对应的 check[i][j] 设置成 true,表明该位置已经访问过了,回溯后需要重置,将 check[i][j] 设置成 false。
时间复杂度是 O(MN4^K), 空间复杂度是 O(M*N)
优化空间
在上一个解题思路中,我们用了一个二维数组 check 来保存搜索路径,其空间复杂度是 O(MN)。其实是没有必要的,我们在搜索到(i, j) 的时候,将对应的 board[i][j] 设置成 *,并将原值保存在一个 temp 变量中,在回溯后在恢复 board[i][j] 的值: board[i][j] = temp。
更好的方案是用二进制操作 异或 的特性: X^Y = Z 一定有 Z^Y = X , 详见最佳提交。
时间复杂度是 O(MN4^K), 空间复杂度是 O(1)
最佳提交
总结
- 可以使用数组(比如二维数组)保存访问过的节点,这样可以防止重复访问节点
- 空间优化的技巧:异或操作
- 回溯的时候需要重置路径值
关于我们
每日一道算法题是一个纯粹的算法学习社区:通过每天一起做一道算法题来提升我们的算法能力。
每日一题算法群现在一共有3000位小伙伴:有来自北美和国内顶尖名校的本科生、研究生和博士生;也有来自国内外各大互联网公司(Google, Facebook, 亚马逊, 百度, 阿里, 腾讯等)的经验丰富的开发者。大家聚集只为一个目的:每天一起学习算法!
我们坚信:学习算法是一种信仰!
长按下面的二维码,关注每日一道算法题公众号,跟我们一起学习算法!