bfs
class Solution {
public:
int getSum(int num) {
int sum = 0;
while (num != 0) {
sum += num % 10;
num /= 10;
}
return sum;
}
int movingCount(int m, int n, int k) {
// k等于0,只有左上角位置满足要求
if (k == 0) return 1;
// visited标记当前位置是否已经被搜索过
// 搜索过为true,没有则为false
vector<vector<bool> > visited(m, vector<bool>(n, false));
int retNum = 0; // 机器人能运动的格子数
queue<vector<int> > q; // 创建存储vector<int>元素的队列
// 将容器初始化为长度为3的数组,数组中每个位置都为0
// 0位置元素为当前遍历位置的横坐标,1位置元素为当前遍历位置的纵坐标,2位置为当前遍历位置的坐标和
// 即初始化的vector容器代表的就是左上角第一个位置元素
vector<int> init = {0, 0, 0};
// 左上角位置入队
q.push(init);
while (q.size() > 0) {
// 取出队列首部元素
vector<int> vec = q.front();
q.pop();
// 获取队列首部元素代表的位置信息
int x = vec[0], y = vec[1], sum = vec[2];
// 判断若遍历的位置越界、坐标和大于k、当前位置已经遍历
// 直接进行下一轮循环
if (x >= m || y >= n || k < sum || visited[x][y]) continue;
// 否则将当前位置标记为已经遍历
visited[x][y] = true;
// 机器人活动范围加一
retNum++;
// 将当前遍历位置的右边和下边的位置入队
// 这样在while循环中,就能广度遍历所有的位置
q.push({x + 1, y, getSum(x + 1) + getSum(y)});
q.push({x, y + 1, getSum(x) + getSum(y + 1)});
}
return retNum;
}
};
作者:RyanWangllng
链接:https://leetcode-cn.com/problems/ji-qi-ren-de-yun-dong-fan-wei-lcof/solution/zhu-shi-xing-ti-jie-shen-du-you-xian-sou-lokj/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
dfs
这个讲的贼好
https://leetcode-cn.com/problems/ji-qi-ren-de-yun-dong-fan-wei-lcof/solution/dfshe-bfsliang-chong-jie-jue-fang-shi-by-sdwwld/
DFS:深度优先搜索
这个图讲的很好 但是底下的程序讲的不行
贴一个自己写的:
注意:c++里二维数组不能bool visited[m][n]
这样传参
vector<vector<bool>> visited(m, vector<bool>(n, 0));
代表一个二维矩阵,m行,每行有n个0
class Solution {
public:
int movingCount(int m, int n, int k) {
// bool visited[m][n];
vector<vector<bool>> visited(m, vector<bool>(n, 0));
return dfs(0,0,m,n,k,visited);
}
int dfs(int i,int j,int m,int n,int k,vector<vector<bool>>& visited){//这个地方传参注意
if(i>=m||j>=n||summ(i,j)>k||visited[i][j]) return false;
visited[i][j]=true;
return 1+dfs(i+1,j,m,n,k,visited)+dfs(i,j+1,m,n,k,visited);
}
int summ(int i,int j){
int sum = 0;
while (i != 0) {
sum += i % 10;
i /= 10;
}
while (j != 0) {
sum += j % 10;
j /= 10;
}
return sum;
}
};
/*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);
}
};
作者:jyd
链接: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/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。*/
BFS:广度优先搜索
public int movingCount(int m, int n, int k) {
//临时变量visited记录格子是否被访问过
boolean[][] visited = new boolean[m][n];
int res = 0;
//创建一个队列,保存的是访问到的格子坐标,是个二维数组
Queue<int[]> queue = new LinkedList<>();
//从左上角坐标[0,0]点开始访问,add方法表示把坐标
// 点加入到队列的队尾
queue.add(new int[]{0, 0});
while (queue.size() > 0) {
//这里的poll()函数表示的是移除队列头部元素,因为队列
// 是先进先出,从尾部添加,从头部移除
int[] x = queue.poll();
int i = x[0], j = x[1];
//i >= m || j >= n是边界条件的判断,k < sum(i, j)判断当前格子坐标是否
// 满足条件,visited[i][j]判断这个格子是否被访问过
if (i >= m || j >= n || k < sum(i, j) || visited[i][j])
continue;
//标注这个格子被访问过
visited[i][j] = true;
res++;
//把当前格子右边格子的坐标加入到队列中
queue.add(new int[]{i + 1, j});
//把当前格子下边格子的坐标加入到队列中
queue.add(new int[]{i, j + 1});
}
return res;
}
//计算两个坐标数字的和
private int sum(int i, int j) {
int sum = 0;
while (i != 0) {
sum += i % 10;
i /= 10;
}
while (j != 0) {
sum += j % 10;
j /= 10;
}
return sum;
}
作者:sdwwld
链接:https://leetcode-cn.com/problems/ji-qi-ren-de-yun-dong-fan-wei-lcof/solution/dfshe-bfsliang-chong-jie-jue-fang-shi-by-sdwwld/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。