// 面试题12:矩阵中的路径
// 题目:请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有
// 字符的路径。路径可以从矩阵中任意一格开始,每一步可以在矩阵中向左、右、
// 上、下移动一格。如果一条路径经过了矩阵的某一格,那么该路径不能再次进入
// 该格子。例如在下面的3×4的矩阵中包含一条字符串“bfce”的路径(路径中的字
// 母用下划线标出)。但矩阵中不包含字符串“abfb”的路径,因为字符串的第一个
// 字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入这个格子。
// A B T G
// C F C S
// J D E H
思路:回溯法就是另类的暴力枚举法,从一个可行的分支下去,一直递归调用,若最后找到了符合条件的,即可
返回,若找不到,再回溯到上一层,从其他分支继续递归。如此循环。
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
using namespace std;
bool hasPath(char *matrix, int rows, int cols, char *str)
{
if (matrix == nullptr || rows <= 0 || cols <= 0 || str == nullptr)
return false;
bool *visited = new bool[rows*cols];
memset(visited, 0,rows*cols);
int pathLength = 0;
for (int row = 0; row < rows; ++row)
{
for (int col = 0; col < cols; ++col)
{
if (hasPathCore(matrix,rows,cols,row,col,pathLength,str,visited))
{
delete[] visited;//原书为什么在 返回false的时候回收 visited,而返回true的时
候,不回收?
return true;
}
}
}
//若没有路径的情况下,需要将分配的visited数组内存释放掉。
delete[] visited;
return false;
}
bool hasPathCore(char *matrix, int rows, int cols, int row,int col,int &pathLength, const
char *str,bool *visited )
{
if (str[pathLength] == '\0')
return true;
bool hasPath = false;
if (row < rows && row >= 0 && col < cols && col >= 0 && matrix[row*cols + col] ==
str[pathLength] && visited[row*cols + col] == false)
{
++pathLength;
visited[row*cols + col] = true;
}
hasPath = hasPathCore(matrix, rows, cols, row + 1, col, pathLength, str, visited)
|| hasPathCore(matrix, rows, cols, row - 1, col, pathLength, str, visited)
|| hasPathCore(matrix, rows, cols, row , col+1, pathLength, str, visited)
|| hasPathCore(matrix, rows, cols, row , col-1, pathLength, str, visited);
if (!hasPath)
{
--pathLength;
visited[row*cols + col] = false;
}
return hasPath;
}
int main()
{
return 0;
}
// 面试题13:机器人的运动范围
// 题目:地上有一个m行n列的方格。一个机器人从坐标(0, 0)的格子开始移动,它
// 每一次可以向左、右、上、下移动一格,但不能进入行坐标和列坐标的数位之和
// 大于k的格子。例如,当k为18时,机器人能够进入方格(35, 37),因为3+5+3+7=18。
// 但它不能进入方格(35, 38),因为3+5+3+8=19。请问该机器人能够到达多少个格子?
思路:这题的回溯是只要遍历符合一个,便要算成功一个,和上一题的区别在于,上一题需要一直走到底,才能
判断合不合适,所以在 回溯的 Core()函数里,有一些小技巧还需要自己多去琢磨。
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
using namespace std;
int moveingCount(int threshold,int rows,int cols)
{
bool *visited = new bool[rows * cols];
memset(visited, 0, rows*cols);
int count = movingCountCore(threshold,rows,cols,0,0,visited);
delete[] visited;
return count;
}
int movingCountCore(int threshold, int rows, int cols, int row, int col, bool *visited)
{
int count = 0;
if (check(threshold, rows, cols, row, col, visited))
{
visited[row*cols + col] = true;
count = 1 + movingCountCore(threshold, rows, cols, row + 1, col, visited)
+ movingCountCore(threshold, rows, cols, row - 1, col, visited)
+ movingCountCore(threshold, rows, cols, row, col + 1, visited)
+ movingCountCore(threshold, rows, cols, row, col-1, visited);
}
return count;
}
bool check(int threshold, int rows, int cols, int row, int col, bool *visited)
{
if(row>=0 && row < rows && col>=0 && col<cols && visited[row*cols + col]==false &&
threshold >= ( getDigitSum(row)+getDigitSum(col) ) )
return true;
return false;
}
int getDigitSum(int num)
{
int sum = 0;
while (num > 0)
{
sum += num % 10;
num /= 10;
}
return sum;
}
int main()
{
return 0;
}