目录
剑指 Offer 12. 矩阵中的路径
题目
代码
class Solution {
public:
bool check(vector<vector<char>>& board, vector<vector<int>>& visited, int i, int j, string& s, int k) {
if (board[i][j] != s[k]) {
return false;
} else if (k == s.length() - 1) {
return true;
}
visited[i][j] = true;
//方向数组
vector<pair<int, int>> directions{{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
bool result = false;
for (const auto& dir: directions) {
int newi = i + dir.first, newj = j + dir.second;
if (newi >= 0 && newi < board.size() && newj >= 0 && newj < board[0].size()) {
if (!visited[newi][newj]) {
bool flag = check(board, visited, newi, newj, s, k + 1);
if (flag) {
result = true;
break;
}
}
}
}
//撤销选择
visited[i][j] = false;
return result;
}
bool exist(vector<vector<char>>& board, string word) {
int h = board.size(), w = board[0].size();
vector<vector<int>> visited(h, vector<int>(w));
//遍历起点
for (int i = 0; i < h; i++) {
for (int j = 0; j < w; j++) {
if (check(board, visited, i, j, word, 0)) {
return true;
}
}
}
return false;
}
};
剑指 Offer 13. 机器人的运动范围
题目
代码
class Solution {
public:
//检查和是否大于k
bool check(int i, int j,int k) {
//i和j最多是两位数
int res = i / 10 + i % 10 + j / 10 + j % 10;
return (res <= k);
}
int dfs(int m, int n, int k, int i, int j,vector<vector<bool>>& visited) {
//只需要向右或者向下
if(i >= m || j >= n || visited[i][j] || !check(i,j,k)) return 0;
visited[i][j]= true;
vector<pair<int, int>>directions = {{1,0},{1,0}};
return 1 + dfs( m, n, k, i + 1, j, visited) + dfs( m, n, k, i, j + 1, visited) ;
}
int movingCount(int m, int n, int k) {
vector<vector<bool>> visited(m,vector<bool>(n));
return dfs(m,n,k,0,0,visited);
}
};
两题对比
很明显,两题都是使用回溯法或者dfs,不同的是12题需要做选择与撤销选择,其次该题在主函数中存在一个for遍历,这是因为题目没有要求固定的起点,所以起点也需要遍历。
13题中需要记录有多少个符合条件的格子,能访问就加一,这个操作不需要撤销,它的主函数中没有使用for遍历是因为起点就是(0,0),我们不能改变。