多一些Aha Time,发现技术的美妙🍺|

啊原来是这样呀

园龄:8年3个月粉丝:3关注:9

【剑指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 };
View Code
复制代码

 

本文作者:啊原来是这样呀

本文链接:https://www.cnblogs.com/OhOfCourse/p/16911370.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   啊原来是这样呀  阅读(24)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起