DFS


题解1:

#include<iostream>
using namespace std;
#include<vector>
bool dfs(vector<vector<char>> matrix, int i, int row, int col, string str) {
	//先找到入口
	if (matrix[row][col] != str[i]) return false;//没找到入口,返回
	//cout << "找到第" << i << "个元素:" << matrix[row][col] << endl;
	//cout << "元素位置:" << row << " " << col << endl;
	matrix[row][col] = '*';//把每次成功找到的走过的路径上的字符设置为*;防止str中存在重复的元素
	i++;//每一次找到了之后,i=i+1
	//找到对应的值之后,找出口
	if (i == str.size()) return true; //当找到的路径数目等于字符长度,那么说明路径已经找到了

	//设置偏移量,要么向上要么向下要么向左要么向右
	int dx[4][2] = { {0,-1},{0,1},
					 {-1,0},{1,0}
	};//分别是向左 向右 向上 向下
	for (int j = 0; j < 4; j++) //每次可以有四个方向进行移动
	{
		row = row + dx[j][0];
		col = col + dx[j][1];
		if (row >= 0 && row < matrix.size() && col >= 0 && col < matrix[0].size())
		{
			if (dfs(matrix, i, row, col, str))  //找到了
				return true;		
		}
		row = row - dx[j][0];//当超出边界,返回现场;当移动之后没找到,返回现场
		col = col - dx[j][1];
	}
	//如果没找到
	return false;
}

bool hasPath(vector<vector<char> >& matrix, string word) {
	// write code here
	int rowLen = matrix.size();//行数
	int colLen = matrix[0].size();//列数
	for (int i = 0; i < rowLen; i++)
	{
		for (int j = 0; j < colLen; j++)
		{
			//cout << "(" << i << "," << j << ")" << endl;
			if (dfs(matrix, 0, i, j, word))
				return true;	
		}
	}
	//回溯法第一个步骤是要找到矩阵的入口单元格,所以在本例中,需要通过循环找到入口的单元格
    //而像机器人的运动范围一例,题目中已经给出了入口的单元格,因此可以直接进行递归调用(在采用DFS)。
	return false;
}


int main() {
	vector<vector<char>> matrix;
	//= { { 'a','b','c','d' },
	//						       { 'e','f','g','h' } ,
	//						       { 'i','j','k','l' } ,
	//						       { 'm','n','o','p'}};
	vector<char> v1 = { 'a','b','c','e','h','j','i','g' };
	vector<char> v2 = { 's','f','c','s','l','o','p','q' };
	vector<char> v3 = { 'a','d','e','e' ,'m','n','o','e' };
	vector<char> v4 = { 'a','d','i','d','e','j','f','m' };
	vector<char> v5 = { 'v','c','e','i','f','g','g','s' };
	matrix.push_back(v1);
	matrix.push_back(v2);
	matrix.push_back(v3);
	matrix.push_back(v4);
	matrix.push_back(v5);

	string str = "sggfiecvaasa";
	cout << "是否存在路径sggfiecvaasa:" << hasPath(matrix, str) << endl;

	system("pause");
	return 0;
}

题解2:

void dfs(vector<vector<char>> matrix, int& count, int row, int col, string str, vector<vector<bool>>& visited) {
	cout <<"坐标变化" << "(" << row << " " << col << ")"<<"找"<<str[count] <<"于"<<count << endl;
	if (row < 0 || row > matrix.size() - 1 || col < 0 || col > matrix[0].size() - 1)
		return; //出口条件:超出边界,返回
	if (matrix[row][col] != str[count])
		return; //出口条件:移动的单元格不是对应的字符,返回
	cout << visited[row][col] << endl;
	if (visited[row][col] == 1)
		return; //出口条件:最终当对应位置全部被走过后,返回

	cout << "找到第" << count << "个--------:" << matrix[row][col];
	cout << "(" << row << " " << col << ")"<<endl;
	//找到对应的字符后
	visited[row][col] = 1;//把每次成功找到的走过的路径上的字符设置为真
	count++;//每一次找到了之后,count=count+1
	if (count == str.size()) return; //所有字符找到,返回

	//开始向四个方向递归
	dfs(matrix, count, row - 1, col, str, visited);
	dfs(matrix, count, row + 1, col, str, visited);
	dfs(matrix, count, row, col - 1, str, visited);
	dfs(matrix, count, row, col + 1, str, visited);
	//如果不采用循环方式进行四个方向的递归,那么就必须在四个方向递归完毕之和,
	//还没有找到对应的字符,说明有重复元素,就需要进行回退,count--;
	//如果全部找到了,返回,count不能再改变,需要作为getIn的判断条件。
	if (count == str.size())
		return;
	else {
		count--;//当四个方向都不是对应字符,说明上一个字符位置不对
		visited[row][col] = 0;//返回时候,count和visited都要更改
	}
}
//找入口位置,即是字符串的第一个元素在矩阵中的位置
bool getIn(vector<vector<char>> matrix,int row, int col, string str) {
	if (matrix[row][col] != str[0]) return false;//没有找到入口,即是第一个字符
	//找到入口,开始递归
	int count = 0;//注意,即使找到了第一个字符,count只能为0,count在递归中自增
	//定义一个bool型二维数组,同时进行初始化,用来存放已经被访问过的单元格
	vector<vector<bool>> visited(matrix.size(), vector<bool>(matrix[0].size(), 0));
	dfs(matrix, count, row, col, str, visited);

	if (count == str.size())//当找到的个数和字符串相同时,返回true,否在返回false;
		return true;
	return false;
}
bool hasPath(vector<vector<char>> matrix, string word) {
	// write code here
	int rowLen = matrix.size();//行数
	int colLen = matrix[0].size();//列数
	//找第一个字符所在位置,如果第一个位置找到了,但是不对,重新查找
	for (int i = 0; i < rowLen; i++)
	{
		for (int j = 0; j < colLen; j++)
		{
			if (getIn(matrix, i, j, word))
				return true;
		}
	}
	return false;
}