考点:回溯法
回溯算法实际上一个类似枚举的搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就“回溯”返回,尝试别的路径。以深度优先的方式搜索解空间。
回溯法非常适合由多个步骤组成的问题,并且每一步都有多个选项。
本题不用回退,较为简单。主要应用深度优先的方式遍历二维空间
题目描述
地上有一个m行和n列的方格。一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格子。 例如,当k为18时,机器人能够进入方格(35,37),因为3+5+3+7 = 18。但是,它不能进入方格(35,38),因为3+5+3+8 = 19。请问该机器人能够达到多少个格子?
思路分析
将方格看作m*n的矩阵,机器人从(0,0)开始移动,当他准备进(i,j)格子,先判断能不能进,判断的标准是当前点没有走过,且满足题目检查坐标数位标准。如果可以进,再判断能否进入4个相邻格子。
1.建bool型visited矩阵标志当前走没有
//C++
bool* visited=new bool[rows*cols]();
#python
visited=[[ False for j in range(cols)] for i in range(rows)]
2.递归深度遍历,实现回溯。check
3.获得数位关系标准函数
实现代码
c++
class Solution {
public:
int movingCount(int threshold, int rows, int cols)
{
if(threshold<0 || rows<1 || cols<1)
return 0;
bool* visited=new bool[rows*cols]();
for(int i=0;i<rows*cols;i++)
visited[i]=false;
int count=movingCountCore(threshold,rows,cols,0,0,visited);
delete[] visited;
return count;
}
int movingCountCore(int threshold,int rows,int cols,int i,int j,bool* visited){
int count=0;
if(checked(threshold,rows,cols,i,j,visited)){
visited[i*cols+j]=true;
count= 1+movingCountCore(threshold,rows,cols,i+1,j,visited)
+movingCountCore(threshold,rows,cols,i-1,j,visited)
+movingCountCore(threshold,rows,cols,i,j+1,visited)
+movingCountCore(threshold,rows,cols,i,j-1,visited);
}
return count;
}
bool checked(int threshold,int rows,int cols,int i,int j,bool* visited){
if(i>=0 && j>=0 && i<rows &&j<cols&& getDigitNum(i)+getDigitNum(j)<=threshold &&visited[i*cols+j]==false)
return true;
return false;
}
int getDigitNum(int num){
int sum=0;
while(num>0){
sum+=(num%10);
num/=10;
}
return sum;
}
python:
- 写法1
class Solution:
def movingCount(self, threshold, rows, cols):
visited=[[ False for j in range(cols)] for i in range(rows)]
return self. moving(threshold,rows,cols,0,0,visited)
def moving(self,threshold,rows,cols,i,j,visited):
count=0
if (i >=0 and i < rows and j >= 0 and j < cols and self.threshhold_check(i,j) <= threshold and visited[i][j] == False):
visited[i][j]=True
count= self.moving(threshold,rows,cols,i,j-1,visited)+self.moving(threshold,rows,cols,i-1,j,visited)+self.moving(threshold,rows,cols,i+1,j,visited)+self.moving(threshold,rows,cols,i,j+1,visited)+1
return count
def threshhold_check(self,i,j):
sum_result=0
while i>0:
sum_result+=i%10
i/=10
while j>0:
sum_result+=j%10
j/=10
return sum_result
注:在类中调用函数需要加self.函数()
- 写法2
class Solution:
def movingCount(self, threshold, rows, cols):
visited=[[ False for j in range(cols)] for i in range(rows)]
def moving(threshold,rows,cols,i,j,visited):
count=0
if (i >=0 and i < rows and j >= 0 and j < cols and self.threshhold_check(i,j) <= threshold and visited[i][j] == False):
visited[i][j]=True
count= moving(threshold,rows,cols,i,j-1,visited)+moving(threshold,rows,cols,i-1,j,visited)+moving(threshold,rows,cols,i+1,j,visited)+moving(threshold,rows,cols,i,j+1,visited)+1
return count
return moving(threshold,rows,cols,0,0,visited)
def threshhold_check(self,i,j):
sum_result=0
while i>0:
sum_result+=i%10
i/=10
while j>0:
sum_result+=j%10
j/=10
return sum_result