leetcode:79. 单词搜索
题目
给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。
单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。
示例:![[中等] 79. 单词搜索 - 图1](/uploads/projects/liangduo-rjrcs@ggu4wq/f9934444445b4ea525084c105f0b9210.jpeg)
输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCCED"输出:true
![[中等] 79. 单词搜索 - 图2](/uploads/projects/liangduo-rjrcs@ggu4wq/049efeace792ba3603150af6cd120639.jpeg)
输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "SEE"输出:true
![[中等] 79. 单词搜索 - 图3](/uploads/projects/liangduo-rjrcs@ggu4wq/3b111e8e06de863b1b4e2fe28e67541a.jpeg)
输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCB"输出:false
解答 & 代码
DFS 深度优先遍历,递归回溯
class Solution {private:bool backTrack(vector<vector<char>>& board, int row, int col, string word, int idx){int rows = board.size();int cols = board[0].size();// 递归结束条件 1:已搜索到完整的单词,直接返回 trueif(idx == word.size())return true;// 递归结束条件 2:网格下标越界,直接返回 falseif(row < 0 || row >= rows || col < 0 || col >= cols)return false;// 递归结束条件 2:当前网格和单词字符不匹配,直接返回 falseif(board[row][col] != word[idx])return false;// 选择:选择当前网格,并修改为 '0',以避免被重复选择board[row][col] = '0';// 递归回溯:上、下、左、右bool up = backTrack(board, row - 1, col, word, idx + 1);bool down = backTrack(board, row + 1, col, word, idx + 1);bool left = backTrack(board, row, col - 1, word, idx + 1);bool right = backTrack(board, row, col + 1, word, idx + 1);// 撤销选择:将当前网格恢复为原字符board[row][col] = word[idx];return up || down || left || right;}public:bool exist(vector<vector<char>>& board, string word) {if(word.size() == 0)return true;if(board.size() == 0 || board[0].size() == 0)return false;int rows = board.size();int cols = board[0].size();for(int row = 0; row < rows; ++row){for(int col = 0; col < cols; ++col){if(board[row][col] == word[0] &&backTrack(board, row, col, word, 0) == true)return true;}}return false;}};
复杂度分析:设网格大小为 M×N,单词长度 L
- 时间复杂度
:遍历 MN 个网格,假设刚好 MN 个网格都和单词首字符相等,则需要进行 MN 次 dfs 查找。每次 dfs 查找,除了第一次可以进入 4 个分支(但上、左也会越界直接返回),其余时间最多都只能进入 3 个分支(不会返回上一步的位置,因为已经被被修改为
'0'以避免重复选择),字符串长度 L,每个位置有 3 个选择,因此时间复杂度 - 空间复杂度 O(L):递归栈深度
执行结果:
执行结果:通过执行用时:532 ms, 在所有 C++ 提交中击败了 35.56% 的用户内存消耗:7.7 MB, 在所有 C++ 提交中击败了 89.55% 的用户
