矩阵中的路径:回溯法,递归与栈。
2017-03-30 10:39
211 查看
题目描述
请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则该路径不能再进入该格子。 例如[a b c e s f c s a d e e]是3*4矩阵,其包含字符串"bcced"的路径,但是矩阵中不包含“abcb”路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入该格子。
解法一:非递归,用栈实现。
注意栈中Node的结构有个direction变量,表示上一次路径走过的方向。
解法二:递归实现:
技巧:能用递归的就不用栈,否则就是自找麻烦!!!
class Solution {
public:
bool hasPath(char* matrix, int rows, int cols, char* str)
{
bool*visited=new bool[rows*cols];
//memset(visited,0,sizeof(visited));
for(int i=0;i<rows*cols;++i) visited[i]=false;//这里果然不能用memset(visited,0,sizeof(visited))
int len=strlen(str);
for (int i = 0; i < rows; ++i)
{
for (int j = 0; j < cols; ++j)
{
if(helper(matrix,rows,cols,i,j,str,0,len,visited))
return true;
}
}
return false;
}
bool helper(char*matrix,int rows,int cols,int i,int j,char* str,int k,int len,bool*visited){
if(k==len) return true;
int index=i*cols+j;
if(i<0||i>=rows||j<0||j>=cols||visited[index]==true||matrix[index]!=str[k])
return false;
//if(k==len-1) return true;
visited[index]=true;
if( helper(matrix,rows,cols,i-1,j,str,k+1,len,visited)
||helper(matrix,rows,cols,i,j+1,str,k+1,len,visited)
||helper(matrix,rows,cols,i+1,j,str,k+1,len,visited)
||helper(matrix,rows,cols,i,j-1,str,k+1,len,visited)
){
return true;}
visited[index]=false;
return false;
}
};
请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则该路径不能再进入该格子。 例如[a b c e s f c s a d e e]是3*4矩阵,其包含字符串"bcced"的路径,但是矩阵中不包含“abcb”路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入该格子。
解法一:非递归,用栈实现。
注意栈中Node的结构有个direction变量,表示上一次路径走过的方向。
struct Node { int i; int j; int direction; Node(int x,int y,int di):i(x),j(y),direction(di){} }; //回溯法使用栈模拟,非递归版本。 class Solution { public: bool hasPath(char* matrix, int rows, int cols, char* str) { vector<vector<char>>m(rows,vector<char>(cols,' ')); for (int i = 0; i < rows; ++i) { for (int j = 0; j < cols; ++j) { m[i][j]=*matrix++; } } vector<vector<bool>>visited(rows,vector<bool>(cols,false)); for (int i = 0; i < rows; ++i) { for (int j = 0; j < cols; ++j) { if(m[i][j]==*str){ str++; if(*str=='\0') return true;//若出现"A",1,1,"A"这种情况防止没有在四方向寻找中得到true,而直接退出stack,在for外面中得到false stack<Node> st; Node curNode(i,j,-1); st.push(curNode); visited[i][j]=true; while(!st.empty()){ Node& curNode=st.top();//reference bool find=false; int r,c; while(curNode.direction<4&&find==false){ curNode.direction++; switch(curNode.direction) { case 0:r=curNode.i-1;c=curNode.j;break; case 1:r=curNode.i;c=curNode.j+1;break; case 2:r=curNode.i+1;c=curNode.j;break; case 3:r=curNode.i;c=curNode.j-1;break; } if(isValidPos(r,c,rows,cols)&&visited[r][c]==false){ if(m[r][c]==*str){ str++; find=true; Node newNode(r,c,-1); st.push(newNode); visited[r][c]=true; } if(*str=='\0') return true; } } if(find==false){ visited[curNode.i][curNode.j]=false; st.pop(); str--; } }//while(!st.empty()) }//if(m[i][j]==*str) } } return false; } bool isValidPos(int x,int y,int rows,int cols){ return (x>=0&&x<rows&&y>=0&&y<cols); } };
解法二:递归实现:
技巧:能用递归的就不用栈,否则就是自找麻烦!!!
class Solution {
public:
bool hasPath(char* matrix, int rows, int cols, char* str)
{
bool*visited=new bool[rows*cols];
//memset(visited,0,sizeof(visited));
for(int i=0;i<rows*cols;++i) visited[i]=false;//这里果然不能用memset(visited,0,sizeof(visited))
int len=strlen(str);
for (int i = 0; i < rows; ++i)
{
for (int j = 0; j < cols; ++j)
{
if(helper(matrix,rows,cols,i,j,str,0,len,visited))
return true;
}
}
return false;
}
bool helper(char*matrix,int rows,int cols,int i,int j,char* str,int k,int len,bool*visited){
if(k==len) return true;
int index=i*cols+j;
if(i<0||i>=rows||j<0||j>=cols||visited[index]==true||matrix[index]!=str[k])
return false;
//if(k==len-1) return true;
visited[index]=true;
if( helper(matrix,rows,cols,i-1,j,str,k+1,len,visited)
||helper(matrix,rows,cols,i,j+1,str,k+1,len,visited)
||helper(matrix,rows,cols,i+1,j,str,k+1,len,visited)
||helper(matrix,rows,cols,i,j-1,str,k+1,len,visited)
){
return true;}
visited[index]=false;
return false;
}
};
相关文章推荐
- 基础算法 | 回溯和递归--矩阵中的路径(编程之美)
- 递归,搜索,回溯,最优路径(线段)
- 矩阵中的路径--79 word Search--DFS回溯
- 回溯之矩阵中的路径
- 递归回溯问题的四道经典题:N皇后,组合,全排列,二叉树路径和
- 矩阵中的路径--回溯
- OJ日常 | 回溯——矩阵中的路径、机器人的运动范围
- 迷宫BFS+递归回溯找爹打印路径
- 求任意大小矩阵两点之间的最短路径(回溯)
- 矩阵中的路径—递归
- 回溯——矩阵中路径问题(0,1矩阵中最优路径、矩阵中的路径、机器人的运动范围)
- 回溯——矩阵中路径问题(0,1矩阵中最优路径、矩阵中的路径、机器人的运动范围)
- 剑指_矩阵中的路径_回溯法
- 回溯——矩阵中路径问题(0,1矩阵中最优路径、矩阵中的路径、机器人的运动范围)
- 回溯——矩阵中路径问题(0,1矩阵中最优路径、矩阵中的路径、机器人的运动范围)
- JAVA回溯, 实现 矩阵中的路径寻找问题
- 回溯——矩阵中路径问题(0,1矩阵中最优路径、矩阵中的路径、机器人的运动范围)
- 回溯法:最大装载问题(使用递归,优化搜索的同时取得最佳路径)
- 回溯——矩阵中路径问题(0,1矩阵中最优路径、矩阵中的路径、机器人的运动范围)
- 递归与动态规划---矩阵的最小路径和