回溯之Leetcode79——Word Search

初看这题,以为这题是逃迷宫那种题,但是后来发现还是有点差别的。这里贴出走迷宫这道题链接:Lost in maze

继续来说这道题,本题判断在一个字符矩阵中,是否可以找出由相邻的元素组成的target字符串。

For example,
Given board =

[
  ['A','B','C','E'],
  ['S','F','C','S'],
  ['A','D','E','E']
]

word
 = 
"ABCCED"
, -> returns 
true
,

word
 = 
"SEE"
, -> returns 
true
,

word = "ABCB", -> returns false.

对比一下那个走迷宫的题,那道题是起点固定,只能从起点出发开始深搜。然而这道题却是起点是矩阵中的任何一个点,所以我们在Main函数中就用一个双重循环,循环起点,然后从每个起点开始深搜。

有点小蓝瘦,做了几道回溯的题了,dfs还是不会写,写了一下午。我用k表示匹配到target字符串的位置,另外visited[][]辅助数组用来标记这个位置是否被检查过。

if(k==word.length())//说明找到一种解。返回1

接下来检查是否出界、被检查过、是否和当前位置的字符匹配。不满足其一都直接return false;(把检查放在第一步是为了防止后面数组越界)

如果满足上述条件,就循环上下左右四个位置,每个位置都进行递归,只要一个位置结果为1,跳出循环返回1;

最后千万别忘了,回溯的过程,将visited清零。是放在for的外面的!

上面的这三个过程的顺序不能变,就这个顺序搞了一下午,得到的一个结论是,dfs判断的是当前的的状态!

下一个位置的放到下一个递归去判断。


另外说一个小细节,我在dfs的参数里把辅助数组visted 数组加了进去,这是错误的,原因是C语言中,二维数组作为形参第二维的维数必须说明

int a[][]

int a[3][]//例如这两个都是错的

而实参可以直接用数组名

详见AC代码:

class Solution {
public:
    int X[4]={0,0,1,-1};int Y[4]={1,-1,0,0};
    bool visited[1000][1000];
    bool exist(vector<vector<char>>& board, string word) {
        int l=board[0].size();int w=board.size();
        memset(visited,0,sizeof(bool));
        for(int i=0;i<w;i++){
            for(int j=0;j<l;j++){
                if(dfs(board,word,i,j,0))
                    return 1;
            }
        }
        return 0;
    }
    bool dfs(vector<vector<char>> &board,string word,int x,int y,int k)
    {
        bool ans;
        if(k==word.length()){return 1;}
        if(x<0||x>=board.size()||y<0||y>=board[0].size()||visited[x][y]||board[x][y]!=word[k]){
            return 0;
        }
        else{
                visited[x][y]=1;
             for(int i=0;i<4;i++) {
                ans= dfs(board,word,x+X[i],y+Y[i],k+1);
                if(ans)break;
            }
        }
        visited[x][y]=0;
        return ans;
    }
};


点赞