Given an m x n grid of characters board and a string word, return true if word exists in the grid.
The word can be constructed from letters of sequentially adjacent cells, where adjacent cells are horizontally or vertically neighboring. The same letter cell may not be used more than once.

Q:给定一个字符表,判断某单词是否在表格中出现。表格中的每个字符最多使用一次,下一个字符必须是上一个字符的相邻字符。

Constraints:

  • m == board.length
  • n = board[i].length
  • 1 <= m, n <= 6
  • 1 <= word.length <= 15
  • board and word consists of only lowercase and uppercase English letters.

Example 1:
image.png
**Input:** board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCCED"
**Output:** true
Example 2:
image.png
**Input:** board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "SEE"
**Output:** true
Example 3:
image.png
**Input:** board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCB"
**Output:** false

方法:深度优先搜索

  1. class Solution {
  2. public:
  3. class Point{
  4. public:
  5. int x; // 行索引
  6. int y; // 列索引
  7. int d; // 方向索引
  8. Point():x(0), y(0), d(0){}
  9. Point(int _x, int _y):x(_x), y(_y), d(0){}
  10. };
  11. bool exist(vector<vector<char>>& board, string word) {
  12. if(word.length() <= 0){
  13. return true;
  14. }
  15. int n = board.size(), m = board[0].size();
  16. stack<Point> path;
  17. for(int i=0; i<n; i++){
  18. for(int j=0; j<m; j++){
  19. if(board[i][j] == word[0] && dfs(board, word, i, j)){
  20. return true;
  21. }
  22. }
  23. }
  24. return false;
  25. }
  26. bool dfs(vector<vector<char>>& board, string& word, int i, int j){
  27. // 在索引i、j处深度优先搜索,查找word
  28. // 已知 board[i][j] == word[0]
  29. int n = board.size(), m = board[0].size();
  30. int offset[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
  31. stack<Point> path;
  32. vector<vector<bool>> visited(n, vector<bool>(m, false));
  33. path.push(Point(i, j));
  34. visited[i][j] = true;
  35. while(path.size() < word.length()){
  36. Point& cp = path.top();
  37. if(cp.d >= 4){
  38. // cp的四个方向都访问过,都不行,需要退出当前节点,回到上一个节点
  39. visited[cp.x][cp.y] = false;
  40. path.pop();
  41. if(path.empty()){
  42. return false;
  43. }
  44. }
  45. else{
  46. Point np;
  47. np.x = cp.x + offset[cp.d][0];
  48. np.y = cp.y + offset[cp.d][1];
  49. cp.d += 1; // 下次再访问该点时的下一个相邻方向
  50. if(isIn(np, n, m) && !visited[np.x][np.y] && board[np.x][np.y] == word[path.size()]){
  51. // 下一个位置在内部、未访问过、且是下一个要访问的字符
  52. path.push(np);
  53. visited[np.x][np.y] = true;
  54. }
  55. }
  56. }
  57. return true;
  58. }
  59. bool isIn(Point p, int n, int m){
  60. if(p.x >= 0 && p.x < n && p.y >= 0 && p.y < m){
  61. return true;
  62. }
  63. return false;
  64. }
  65. };

运行效率评价:

Success Details
Runtime: 752 ms, faster than 17.20% of C++ online submissions for Word Search.
Memory Usage: 7.8 MB, less than 5.08% of C++ online submissions for Word Search.