题目分析:[[EVD]] - 剑指 Offer 13. 机器人的运动范围
https://leetcode-cn.com/problems/ji-qi-ren-de-yun-dong-fan-wei-lcof/
简单描述:
- 机器人在网格内移动,能到达的格子数
限制🚫
- 1 <= n,m <= 100
- 0 <= k <= 20
示例:
输入:m = 2, n = 3, k = 1
输出:3
解题思路:
思路:
- #DFS #BFS 深搜找到连续可达的格子总数cnt
- 根据可达解为多个等腰三角形组成,可简化搜索方向为向下向右,详见大佬题解
- 大佬题解
https://leetcode-cn.com/problems/ji-qi-ren-de-yun-dong-fan-wei-lcof/solution/mian-shi-ti-13-ji-qi-ren-de-yun-dong-fan-wei-dfs-b/
效率:
- 时间复杂度
- 空间复杂度
代码:
- DFS
class Solution
{
private:
int row, col, cnt = 0;
bool vis[100 + 5][100 + 5] = {0};
bool dfs(int i, int j, int k)
{
if (i < 0 || j < 0 || i >= row || j >= col || (sums(i) + sums(j) > k) || vis[i][j])
return false;
cnt++;
vis[i][j] = 1;
//return dfs(i, j - 1, k) || dfs(i, j + 1, k) || dfs(i - 1, j, k) || dfs(i + 1, j, k);
return dfs(i, j + 1, k) || dfs(i + 1, j, k);
}
int sums(int x)
{
int s = 0;
while (x)
{
s += x % 10;
x /= 10;
}
return s;
}
public:
/*dfs+vis访问数组(无须回溯,不求深度)*/
int movingCount(int m, int n, int k)
{
row = m, col = n;
dfs(0, 0, k);
return cnt;
}
};
- 大佬的DFS,针对百位以内求数位和有神奇的操作
class Solution
{
public:
/*大佬代码,简化搜索方向和百位以内数位和计算*/
int movingCount(int m, int n, int k)
{
vector<vector<bool> > visited(m, vector<bool>(n, 0));
return dfs(0, 0, 0, 0, visited, m, n, k);
}
private:
int dfs(int i, int j, int si, int sj, vector<vector<bool> > &visited, int m, int n, int k)
{
if (i >= m || j >= n || k < si + sj || visited[i][j])
return 0;
visited[i][j] = true;
return 1 + dfs(i + 1, j, (i + 1) % 10 != 0 ? si + 1 : si - 8, sj, visited, m, n, k) +
dfs(i, j + 1, si, (j + 1) % 10 != 0 ? sj + 1 : sj - 8, visited, m, n, k);
//本题1≤n,m≤100,仅适用于此的数位和增量公式: (x + 1) % 10 != 0 ? s_x + 1 : s_x - 8;
}
};