leetcode:79. 单词搜索

题目

给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false
单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。

示例:
[中等] 79. 单词搜索 - 图1

  1. 输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCCED"
  2. 输出:true

[中等] 79. 单词搜索 - 图2

  1. 输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "SEE"
  2. 输出:true

[中等] 79. 单词搜索 - 图3

  1. 输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCB"
  2. 输出:false

解答 & 代码

DFS 深度优先遍历,递归回溯

  1. class Solution {
  2. private:
  3. bool backTrack(vector<vector<char>>& board, int row, int col, string word, int idx)
  4. {
  5. int rows = board.size();
  6. int cols = board[0].size();
  7. // 递归结束条件 1:已搜索到完整的单词,直接返回 true
  8. if(idx == word.size())
  9. return true;
  10. // 递归结束条件 2:网格下标越界,直接返回 false
  11. if(row < 0 || row >= rows || col < 0 || col >= cols)
  12. return false;
  13. // 递归结束条件 2:当前网格和单词字符不匹配,直接返回 false
  14. if(board[row][col] != word[idx])
  15. return false;
  16. // 选择:选择当前网格,并修改为 '0',以避免被重复选择
  17. board[row][col] = '0';
  18. // 递归回溯:上、下、左、右
  19. bool up = backTrack(board, row - 1, col, word, idx + 1);
  20. bool down = backTrack(board, row + 1, col, word, idx + 1);
  21. bool left = backTrack(board, row, col - 1, word, idx + 1);
  22. bool right = backTrack(board, row, col + 1, word, idx + 1);
  23. // 撤销选择:将当前网格恢复为原字符
  24. board[row][col] = word[idx];
  25. return up || down || left || right;
  26. }
  27. public:
  28. bool exist(vector<vector<char>>& board, string word) {
  29. if(word.size() == 0)
  30. return true;
  31. if(board.size() == 0 || board[0].size() == 0)
  32. return false;
  33. int rows = board.size();
  34. int cols = board[0].size();
  35. for(int row = 0; row < rows; ++row)
  36. {
  37. for(int col = 0; col < cols; ++col)
  38. {
  39. if(board[row][col] == word[0] &&
  40. backTrack(board, row, col, word, 0) == true)
  41. return true;
  42. }
  43. }
  44. return false;
  45. }
  46. };

复杂度分析:设网格大小为 M×N,单词长度 L

  • 时间复杂度 [中等] 79. 单词搜索 - 图4:遍历 MN 个网格,假设刚好 MN 个网格都和单词首字符相等,则需要进行 MN 次 dfs 查找。每次 dfs 查找,除了第一次可以进入 4 个分支(但上、左也会越界直接返回),其余时间最多都只能进入 3 个分支(不会返回上一步的位置,因为已经被被修改为 '0' 以避免重复选择),字符串长度 L,每个位置有 3 个选择,因此时间复杂度 [中等] 79. 单词搜索 - 图5
  • 空间复杂度 O(L):递归栈深度

执行结果:

  1. 执行结果:通过
  2. 执行用时:532 ms, 在所有 C++ 提交中击败了 35.56% 的用户
  3. 内存消耗:7.7 MB, 在所有 C++ 提交中击败了 89.55% 的用户