class Solution { public: bool hasPath(char* matrix, int rows, int cols, char* str) { if (*matrix == '\0' || *str == '\0') return false; int length = rows*cols; for (int i = 0; i != length; ++i,++matrix){ if (*str == *matrix){ set<int> route; route.insert(i); // 在matrix四周寻找*++str元素 auto res = find(matrix, str+1, i, route, length, cols); if (res) return true; } } return false; } bool find(char* matrix, char* str, int i, set<int> &route, int &length, int &cols){ if (*str == '\0') return true; // 上下左右四次判断是不能改变原始参数 // 查看上边元素 if ((i - cols) >= 0 && (i - cols) < length && route.find(i - cols) == route.end()){ matrix -= cols; if (*matrix == *str){ route.insert(i - cols); auto res = find(matrix, str+1, i - cols, route, length, cols); if (res) return true; else{ route.erase(i - cols); } } matrix += cols; } // 查看下边元素 if ((i + cols) >= 0 && (i + cols) < length && route.find(i + cols) == route.end()){ matrix += cols; if (*matrix == *str){ route.insert(i + cols); auto res = find(matrix, str+1, i + cols, route, length, cols); if (res) return true; else{ route.erase(i + cols); } } matrix -= cols; } // 查看左边元素 if ((i - 1) >= 0 && (i - 1) < length && route.find(i - 1) == route.end()){ matrix -= 1; if (*matrix == *str){ route.insert(i - 1); auto res = find(matrix, str+1, i - 1, route, length, cols); if (res) return true; else{ route.erase(i - 1); } } matrix += 1; } // 查看右边元素 if ((i + 1) >= 0 && (i + 1) < length && route.find(i + 1) == route.end()){ matrix += 1; if (*matrix == *str){ route.insert(i + 1); auto res = find(matrix, str+1, i + 1, route, length, cols); if (res) return true; else{ route.erase(i + 1); } } matrix -= 1; } // 上下左右都不行 return false; } };
太不容易了,之前看到这种题想都不敢想,这次先想再写后调竟然搞出来了。
首先搜了一下回溯是啥意思“回溯:搜索尝试的枚举,当 不符合条件时 返回尝试别的路径”
haspath函数是比较当前matrix字符是否等于str的头字符,符合条件进入find函数,find函数的作用是搜索matrix该位置的上下左右位置是否有等于str的下一个字符。(类似一个递归的思想)
注意的问题有:
1、这里排除走重复路的措施是用一个set记录走过点的序号,要注意序号和指针的对应
2、因为在不断尝试,所以不满足要求退出时,matrix,str相关的指针序号要退回到尝试前的状态(错的四次里三次都是这里的问题)。
欢迎交流指正!!!