LeetCode | 79. 单词搜索

原题Medium):

  给定一个二维网格和一个单词,找出该单词是否存在于网格中。

  单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。

      

思路:回溯

  建立一个xy坐标系,通过4个坐标实现在网格中上下左右地逐格移动,而判断能否移动的条件自然就是:是否越界(要大于等于0,小于网格大小)。另外需一个二维访问数组与网格对标,记录网格中的被访问情况。

  而回溯的思路是:除了主函数以外,还需一递归函数(取名为DFS),递归函数在通过4个坐标获知移动的方向,若符合移动的条件,递归调用DFS进行网格内移动,若当前字符与字符串当前索引的字符相等,设置该网格已访问并递增索引,然后继续移动......递归往上返回的条件是索引与字符串长度相等(返回T),或者当前字符与字符串当前索引字符不想等(返回F),或者相等,但邻近所有字符与字符串下一索引字符不相等(返回F)。

 1 class Solution {
 2 public:
 3     int dir[4][4] = { { -1,0 },{ 1,0 },{ 0,1 },{ 0,-1 } };        //4个方向坐标,分别代表往左、右、上、下移动一格
 4     bool DFS(vector<vector<char>>& board, int index, int x, int y, vector<vector<bool>>& visited, string& word)
 5     {
 6         //移动后当前网格字符与字符串当前索引字符比较
 7         if (board[x][y] == word[index] && index<word.length())
 8         {
 9             //相等,索引递增,该格设为已访问
10             index++;
11             visited[x][y] = true;
12         }
13         else
14         {    //否则,返回false,回退至上一DFS
15             return false;
16         }
17         //索引与字符串长度相等,说明该单词存在于网格中,结束递归,返回true
18         if (index == word.length()) return true;
19 
20         //4个移动方向都进行尝试
21         for (int i = 0; i<4; i++)
22         {
23             x += dir[i][0];
24             y += dir[i][1];
25 
26             //若该方向不越界,往其前进一格,并递归调用DFS
27             if (x >= 0 && x<board.size() && y >= 0 && y<board[0].size() && !visited[x][y])
28                 if (DFS(board, index, x, y, visited, word))    //若T,说明递归结束,继续往上返回T
29                     return true;
30 
31             //若进行到此,说明该方向越界或者字符不匹配,返回到原来的位置上。
32             x -= dir[i][0];
33             y -= dir[i][1];
34         }
35         //若进行到此,说明当前网格字符的所有邻近字符都与字符串当前索引字符不匹配,说明此路不通,撤销该网格已访问的记录,并继续往上返回F
36         visited[x][y] = false;
37         return false;
38     }
39 
40     //主函数
41     bool exist(vector<vector<char>>& board, string word) {
42         int row = board.size();
43         int col = board[0].size();
44         vector<vector<bool>>visited(row, vector<bool>(col, false));    //二维访问数组
45 
46         //遍历网格,寻找一个合适的开始位置,即该网格中与字符串第一个字符相等的那一格
47         for (int i = 0; i < row; i++)
48             for (int j = 0; j < col; j++)
49                 if (DFS(board, 0, i, j, visited, word))
50                     return true;
51         return false;
52     }
53 };

 

猜你喜欢

转载自www.cnblogs.com/MisakiJH/p/11667897.html