1.考点
- 考点1:对于二维数组的遍历理解,其往往是个一维数组存储,将其理解为二维数组,那么在知道二维数组的行rows与列cols的情况下,任意的位置即为row*cols+col;
- 考点2:试探回溯法在不同的寻路问题中的使用情况,比如本题其实主要是使用了深度优先的试探方法,其回溯过程其实并没有很明显的体现,主要就是在完成一个分支后return count值,而随着分支的不断结束而不断地进行下一个递归式子的过程其实就是回溯。
- 考点3:BFS算法:广度优先搜索算法和深度优先搜索算法的本质不同在对于上下左右的走法处理上,其往往是通过不断地循环所要走的方向,然后通过队列来出队获取节点,而不是DFS的递归或栈。
2.代码
- 总结了相关的试探回溯法解题思路如下:
- (1)分析问题:问题往往分两种,一种是经典的一维数组/二维数组存储数据,一种是采用自定义的节点来实现存储过程,前者适合使用递归的方式来实现试探回溯,因为需要将源数据数组不断地调用;而后者没有源数据数组,所以适合使用栈存储的方式来实现试探回溯。不过后者也有个问题,即如何实现上下左右移动时如何保证每次式子中的数据就是原始的node点,而不是上一步移动后的node点。(以下都以递归情况开始写)
- (2)确定起点与约束条件:起点可能是定死的比如(0,0),也有可能是遍历所有的点,也有可能是选择某些点,所以需要一些操作来先适应起点的选取(比如直接输入单点,或者通过循环不断地更换起点);约束条件则根据题目中了解到底有什么限制(比如坐标不能大于多少啦,路径要跟着给定的走啊之类的)
- (3)试探回溯函数A:通过起点的选择与基本的前置条件确定(比如行列在规定值内),再写试探回溯函数A,其中A中往往需要传入主函数的所有参数,以及相关的行列位置。而进入A之后,往往要判断前置条件(因为会不断递归A函数所有还需要判断)与约束条件,如果可以的话则进入递归函数组(内部进行上下左右等操作),如果不可以的话进行回溯或返回值等操作;
- (4)A中的多种特例:比如前置条件与约束条件的判断较为复杂,需要辅助函数check来实现,比如内部的上下左右移动不方便,需要别的函数来辅助之类的。
class Solution
{
public:
int movingCount(int threshold, int rows, int cols)
{
if (threshold < 0 || rows < 0 || cols < 0)
return 0;
bool* isVisited = new bool[rows*cols];
memset(isVisited, false, rows*cols);
int count = movingCountByPoint(threshold, rows, cols, 0, 0, isVisited);
delete[] isVisited;
return count;
}
int movingCountByPoint(int threshold, int rows, int cols, int row, int col, bool* isVisited)
{
int count = 0;
if (check(threshold, rows, cols, row, col, isVisited))
{
isVisited[row*cols + col] = true;
count = 1 + movingCountByPoint(threshold, rows, cols, row + 1, col, isVisited)
+ movingCountByPoint(threshold, rows, cols, row - 1, col, isVisited)
+ movingCountByPoint(threshold, rows, cols, row, col + 1, isVisited)
+ movingCountByPoint(threshold, rows, cols, row, col - 1, isVisited);
}
return count;
}
bool check(int threshold, int rows, int cols, int row, int col, bool* isVisited)
{
if (row >= 0 && row < rows && col >= 0 && col < cols && !isVisited[row*cols + col])
{
int sum = 0;
while (row)
{
sum += row % 10;
row /= 10;
}
while (col)
{
sum += col % 10;
col /= 10;
}
return (sum <= threshold);
}
return false;
}
};