本题难度:Mediumjavascript
作题日期:2017年3月24日java
本题地址: 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 字符串 是否符合条件。以下图一spa
假设咱们已经肯定了起始点为 S ,其位置坐标是(1, 0) 。此时,咱们须要判断字符S(1,0) 周边是否有第二个字符A,此时有四个能够选择路径:3d
在上一个步骤,咱们已经肯定了 SA ,接下来肯定 D。 其状态以下图二所示code
根据上一个步骤的分析,在 A(0, 0) 咱们也有四个选择:cdn
在上面的分析中的第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, 亚马逊, 百度, 阿里, 腾讯等)的经验丰富的开发者。你们汇集只为一个目的:天天一块儿学习算法!
咱们坚信:学习算法是一种信仰!
长按下面的二维码,关注每日一道算法题公众号,跟咱们一块儿学习算法!