【剑指offer】50.矩阵中的路径
总目录:
1.问题描述
请设计一个函数,用来判断在一个n乘m的矩阵中是否存在一条包含某长度为len的字符串所有字符的路径。
路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则该路径不能再进入该格子。
例如
[a,b,c,e;
s,f,c,s;
a,d,e,e]矩阵中包含一条字符串"bcced"的路径,但是矩阵中不包含"abcb"路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入该格子。
数据范围:0≤n,m≤20,1≤len≤25
2.问题分析
1回溯法
先在大循环里找到匹配的入口,然后上下左右找下一个匹配的字符进行递归,需要使用一个全局表来记录某个坐标是否已经被占用
3.代码实例
回溯法,很笨的实现

1 class Solution { 2 public: 3 /** 4 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 5 * 6 * 7 * @param matrix char字符型vector<vector<>> 8 * @param word string字符串 9 * @return bool布尔型 10 */ 11 //辅助空间 12 const char illigalChar = '\0'; 13 int rowCnt, colCnt, charCnt; 14 vector<vector<bool>> flagMat; 15 16 //按方向步进 17 bool getNextLocation(const int dir, const int curRow, const int curCol, 18 int& newRow, 19 int& newCol) { 20 newRow = 0; 21 newCol = 0; 22 23 switch (dir) { 24 case 0: 25 if (curRow <= 0) return false; 26 newRow = curRow - 1; 27 newCol = curCol; 28 break; 29 case 1: 30 if (curCol <= 0) return false; 31 newRow = curRow; 32 newCol = curCol - 1; 33 break; 34 case 2: 35 if (curRow >= (rowCnt - 1)) return false; 36 newRow = curRow + 1; 37 newCol = curCol; 38 break; 39 case 3: 40 if (curCol >= (colCnt - 1)) return false; 41 newRow = curRow; 42 newCol = curCol + 1; 43 break; 44 default: 45 break; 46 } 47 48 return true; 49 } 50 51 //按方向匹配 52 char getNearChar(vector<vector<char> >& matrix, const int curRow, 53 const int curCol, 54 int dir) { 55 //dir 0-上,1-左,2-下,3-右 56 int newRow, newCol; 57 bool canNext = getNextLocation(dir, curRow, curCol, newRow, newCol); 58 if (!canNext) { 59 return illigalChar; 60 } 61 return flagMat[newRow][newCol] 62 ? illigalChar : matrix[newRow][newCol] ; 63 } 64 65 //蔓延,递归 66 int depth = 0; 67 bool Spread(vector<vector<char> >& matrix, const int curRow, const int curCol, 68 string word, int tgtCharId) { 69 printf("depth=%d", depth++); 70 71 //中止条件,该搜索的已经搜索完 72 if (tgtCharId >= charCnt) { 73 return true; 74 } 75 76 //遍历方向 77 //dir 0-上,1-左,2-下,3-右 78 bool isMatch = false; 79 bool canNext = false; 80 int newRow = 0, newCol = 0; 81 for (int dir = 0; dir < 4; dir++) { 82 //指定方向的字符不匹配 83 if (getNearChar(matrix, curRow, curCol, dir) != word[tgtCharId]) { 84 continue; 85 } 86 87 //在字符继续搜索 88 getNextLocation(dir, curRow, curCol, newRow, newCol); 89 flagMat[newRow][newCol] = true;//标记占用 90 isMatch = Spread(matrix, newRow, newCol, word, tgtCharId + 1); 91 if (isMatch) { 92 return true; 93 } 94 flagMat[newRow][newCol] = false;//解除占用 95 } 96 97 return false; 98 } 99 100 101 //程序入口 102 bool hasPath(vector<vector<char> >& matrix, string word) { 103 //边界保护 104 if (matrix.size() <= 0 || matrix[0].size() <= 0) { 105 if (word.size() > 0) { 106 return false; 107 } 108 } 109 110 //辅助空间 111 rowCnt = matrix.size(); 112 colCnt = matrix[0].size(); 113 charCnt = word.size(); 114 for (int rowId = 0; rowId < rowCnt; rowId++) { 115 flagMat.push_back(vector<bool>(colCnt, false)); 116 } 117 118 //边界保护 119 if (rowCnt * colCnt < charCnt) { 120 return false; 121 } 122 123 //从首字符开始 124 bool isMatch = false; 125 for (int curRow = 0; curRow < rowCnt; curRow++) { 126 for (int curCol = 0; curCol < colCnt; curCol++) { 127 //匹配首字符 128 if (matrix[curRow][curCol] != word[0]) { 129 continue; 130 } 131 132 //找到入口,蔓延搜索 133 flagMat[curRow][curCol] = true;//标记占用 134 isMatch = Spread(matrix, curRow, curCol, word, 1); 135 if (isMatch) { 136 return true; 137 } 138 flagMat[curRow][curCol] = false;//解除占用 139 } 140 } 141 142 return isMatch; 143 } 144 };
本文作者:啊原来是这样呀
本文链接:https://www.cnblogs.com/OhOfCourse/p/16911370.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步