题目
地上有一个m行n列的方格,从坐标 [0,0] 到坐标 [m-1,n-1] 。一个机器人从坐标 [0, 0] 的格子开始移动,它每次可以向左、右、上、下移动一格(不能移动到方格外),也不能进入行坐标和列坐标的数位之和大于k的格子。例如,当k为18时,机器人能够进入方格 [35, 37] ,因为3+5+3+7=18。但它不能进入方格 [35, 38],因为3+5+3+8=19。请问该机器人能够到达多少个格子?
示例1:
输入:m = 2, n = 3, k = 1
输出:3
示例2:
输入:m = 3, n = 1, k = 0
输出:1
深度遍历:
class Solution(object):
def moving(self,m,n,k):
def dfs(i,j,si,sj):
if i>=m or j>=n or k<si+sj or (i,j) in visited:
return 0
visited.add((i,j))
return 1+dfs(i+1,j,si+1 if(i+1)%10 else si-8,sj) \
+dfs(i,j+1 si,sj+1 if(j+1)%10 else sj-8)
visited=set()
return dfs(0,0,0,0)
此处的si+1 if(i+1)%10 else si-8 是指,si是i值的数位和,而数位和的得出 分为两种情况
1、是两位数,那么i是从0-9的范围,假设x=11,那么它的数位和是2,那么12的数位和就是3 所以12%10!=0 sx+1是在此题是符合的;
x=10 所以11的数位和是10-8=2,也符合。
广度遍历:
步骤:
1、初始化机器人初始化点为(0,0)
2、迭代终止条件:queue为空。
3、迭代工作:
(1)单元格出队:将队首单元格的索引、数位和 弹出,作为当前搜索单元格
(2)判断是否跳过:如果<1> 行列越界<2>数位和超出k,<3>已经访问过,执行continue
(3)标记当前单元格到visited
(4) 单元格入队:将元素下方、右方单元格索引、数位和加入queue
class Solution(object):
def moving(self,m,n,k):
queue=[(0,0,0,0)]
visited=set()
while(queue):
i,j,si,sj=queue.pop()
if(i>=m or j>=n or (i,j) in visited):
continue
visited.add((i,j))
queue.append((i+1,j,si+1 if (i%10) else si-8,sj))
queue.append((i,j+1,si,sj+1 if (j%10) else sj-8))
return len(queue)
C++ 版本
class Solution {
public:
int movingCount(int m, int n, int k) {
vector<vector<bool>> visited(m,vector<bool>(n,0));
int res = dfs(0,0,0,0,visited,m,n,k);
return res;
}
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;
int res=1+dfs(i+1,j,adjust(i+1,si),sj,visited,m,n,k)+dfs(i,j+1,si,adjust(j+1,sj),visited,m,n,k);
return res;
}
int adjust(int index,int sum){
int result;
if ((index+1)%10) result=sum+1;
else result=sum-8;
return result;
}
};
这个版本报错了,结果错误;
就是因为dfs接收visited的时候,没有写引用符号,导致visited没有更新i,j
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);
}
};
广度搜索
class Solution{
public:
int movingCount(int m,int n,int k){
vector<vector<bool>> visited(m,vector<bool>(n,0));
int res=0;
queue<vector<int>> que;
que.push({0,0,0,0});
while(que.size()>0){
vector<int> x=que.front();
que.pop();
int i=x[0],j=x[1],si=x[2],sj=x[3]'
if(i>=m||j>=n||k<si+sj||visited[i][j]) continue;
visited[i][j]=true;
res++;
que.push({i+1,j,(i+1)%10!=0? si+1:si-8,sj});
que.push({i,j+1,i,(j+1)%10!=0? sj+1:sj-8});
}
return res;
}
};