矩阵中的路径(回溯法)

请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一格开始,每一步可以在矩阵中向左、右、上、下移动一格。如果一条路径经过了矩阵的某一格,那么该路径不能再次进入该格子。例如,在下面的3×4的矩阵中包含一条字符串“bfce”的路径。
[[“a”,“b”,“c”,“e”],
[“s”,“f”,“c”,“s”],
[“a”,“d”,“e”,“e”]]
但矩阵中不包含字符串“abfb”的路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入这个格子。
示例 1:
输入:board = [[“A”,“B”,“C”,“E”],[“S”,“F”,“C”,“S”],[“A”,“D”,“E”,“E”]], word = “ABCCED”
输出:true
示例 2:
输入:board = [[“a”,“b”],[“c”,“d”]], word = “abcd”
输出:false

方法一:(未通过)
先想了一种用哈希集合记录走过的路径。先把字符串第一个数在数组中的位置找到,然后从这个位置开始上下左右移动,如果找不到就return false。

代码记录一下:

class Solution {
public:   
    bool exist(vector<vector<char>>& board, string word) {
        if(board.size()==0||board[0].size()==0)return false;
        int gao=board.size();
        int kuan=board[0].size();
        int i,j;
        int flag=0;
       // vector<int>count;
        for( i=0;i<gao;++i){
            for( j=0;j<kuan;++j){
                if(board[i][j]==word[0]){
                    flag=1;
                    break;//count.push_back(i*10+j);
                }
                if(flag==1)break;
            }
        }
        if(flag==0)return false;
    //while(!count.empty()){
       // i=count[count.size()-1]/10;
       // j=count[count.size()-1]%10;
       // count.pop_back();
        
       // int len=word.size();
        unordered_set<int> visited;
        visited.insert(i*10+j);
      //  len=len-1;
        int k=1;
        while(k<word.size()){
            if(i-1>=0&&board[i-1][j]==word[k]&&(!visited.count(10*(i-1)+j))){
                visited.insert((i-1)*10+j);
                i=i-1;
              //  len--;
            }
            else if(i+1<gao&&board[i+1][j]==word[k]&&(!visited.count(10*(i+1)+j))){
                visited.insert((i+1)*10+j);
                i=i+1;
             //   len--;
            }
            else if(j-1>=0&&board[i][j-1]==word[k]&&(!visited.count(10*i+j-1))){
                visited.insert(i*10+j-1);
                j=j-1;
             //   len--;
            }
            else if(j+1<kuan&&board[i][j+1]==word[k]&&(!visited.count(10*i+j+1))){
                visited.insert(i*10+j+1);
                j=j+1;
            //    len--;
            }
            else return false;//else break;
            k++;
        //}
        //if(len==0)return true;
    }
        return true;
    }
};

在这里插入图片描述
在这个测试例子中没有通过,我写的这个应该是针对数组中没有重复数字是可行的(部分有重复数字的也可行)。
后来我又想,那是不是可以找个数组记录所有字符串第一个数字出现的位置。然后依次根据不同的位置进行查找。(代码里注释部分)。

然后我发现了一个问题,在这个不通过的例子里,查找第二个数时也有不同的路径,所以在循环里那四个if 的先后顺序就会捣乱。如果继续这样做,还要再加循环。太麻烦了,还是乖乖的回溯去吧。T_T

方法二:回溯法
回溯法+深度遍历。用递归
dfs的思路与这道题有相似之处 岛屿数量

class Solution {
public:  
    bool dfs(vector<vector<char>>& board, string word,int i,int j,int gao,int kuan,int num){
        if(num==word.size())return true;
        int x[4] = {0,0,-1,1};
        int y[4] = {-1,1,0,0};
        char tmp=board[i][j];
        board[i][j]='.';//访问过这个点就把他沉降掉
        for(int k=0;k<4;k++){
            int dx=x[k]+i;
            int dy=y[k]+j;
            if(dx>=0&&dx<gao&&dy>=0&&dy<kuan&&word[num]==board[dx][dy])
                if(dfs(board,word,dx,dy,gao,kuan,num+1))return true;
        }
        board[i][j]=tmp;
        return false;
    }

    bool exist(vector<vector<char>>& board, string word) {
        if(board.size()==0||board[0].size()==0)return false;
        int gao=board.size();
        int kuan=board[0].size();
        for(int i=0;i<gao;++i){//与方法一相似,先找到字符串的第一个字符,然后进入递归。
            for(int j=0;j<kuan;++j){
                if(board[i][j]==word[0])
                    if(dfs(board,word,i,j,gao,kuan,1))return true;
            }
        }
        return false;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值