Word Search(深度搜索DFS,参考)

Given a 2D board and a word, find if the word exists in the grid.

The word can be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once.

For example,
Given board =

[
  ["ABCE"],
  ["SFCS"],
  ["ADEE"]
]

word = "ABCCED", -> returns true,
word = "SEE", -> returns true,
word = "ABCB", -> returns false.

头次接触这类题目,对我来说还是有难度的,其实这类题的难点就在于,单纯的DFS,是无法在回溯到某一点的时候去改变该点的状态,因为你无法判断回溯到了哪一点(至少我没有做出来~)。那么用一个for循环,里面是递归这种形式,可以做到的,我想这就是回溯和所谓的DFS的区别吧。

我做过的与该题类似的题目:

Letter Combinations of a Phone Number(带for循环的DFS,组合问题,递归总结)

leedcode:Combinations

  算法核心:回溯在现实生活中就是一种试探的尝试,例如,你很久以前去过一个地方,只很清楚记得目的地的一个特征(假设到时你能知道),现在你在一个十字路口,不知哪个方向是目的地所在的方向,那就只能选择一个方向进行试探,如果运气不好的话,错了,就只能回到十字路口,在进行下一个方向的尝试,这个回到十字路口就是一种回溯

  回到该题思路:首先找到头节点,然后开始深搜,深搜的过程需要记录该点是否被纳入到我们的路径中,因为每个点是只能用一次的。

  错误DFS代码,因为他在回溯的时候无法改变已经访问过的点,如果我们在某一点a[i][j]处,它的上下都能走,但是上只能走一步(也就是说a[i-1][j]的上下左右都是不符合条件的),所以我们在回到a[i][j]处的时候需要把刚刚向上走的那一点(a[i-1][j])的访问状态置回false,因为该点可能在以后成为我们需要再次访问的点,但是现在我们并没有把该点加入到我们的路径中:

class Solution {
private:
  vector<vector<char>> m_board;
  bool visited[100][100];
  string m_word;
  int max_row;
  int max_col;
public:
  bool dfs(int dep,int i,int j)
  {
    if(i<0||i==max_row||j<0||j==max_col)
      return false;
    if(m_board[i][j]!=m_word[dep])
      return false;
    if(dep!=m_word.size()-1)
      visited[i][j]=true;
    if(visited[i][j]==false&&dep==m_word.size()-1)
      return true;

    return dfs(dep+1,i-1,j)||dfs(dep+1,i+1,j)||dfs(dep+1,i,j-1)||dfs(dep+1,i,j+1);//某一层的上下左右都无路的时候,要把访问标志置回false
  }
  bool exist(vector<vector<char>> &board, string word) {
    //找到起始位置
    m_board=board;
    m_word=word;
    max_row=m_board.size();
    max_col=m_board[0].size();
    for (int i=0;i<max_row;++i)
    {
      for (int j=0;j<max_col;++j)
      {
        if(m_board[i][j]==m_word[0]){
          memset(tag,0,sizeof(tag));          visited[i][j]=true;
          if(dfs(0,i,j))
            return true;
          else {          continue;        visited[i][j]=false;        }
        }
      }
    }
    return false;
  }
};

简单说下我的理解:以前一个点为基础,来搜索它的上下左右,若搜到一点,则一直往下,直到”撞墙“或者不满足条件,就回溯。就是这种走到顶,然后回溯,又走又回溯,直到找到最后的结果。

参考代码:

const int MAX=100;
int dire[4][2]={-1,0,1,0,0,-1,0,1};
bool visited[MAX][MAX];
class Solution {
private:
    vector<vector<char>> m_board;
    string m_word;
    int max_row;
    int max_col;
    bool res;
public:
    void dfs(int dep,int i,int j)
    {
        if(dep==m_word.size()){
            res=true;
            return;
        }
        for (int q=0;q<4;++q)
        {
            int newi=dire[q][0]+i;
            int newj=dire[q][1]+j;
            if(newi>=0&&newi<max_row&&newj>=0&&newj<max_col&&m_board[newi][newj]==m_word[dep]&&!visited[newi][newj])
            {
                visited[newi][newj]=true;
                dfs(dep+1,newi,newj);
                visited[newi][newj]=false;//该位置上下左右都不通
            }
        }
    }
    bool exist(vector<vector<char>> &board, string word) {
        //找到起始位置
        res=false;
        m_board=board;
        m_word=word;
        max_row=m_board.size();
        max_col=m_board[0].size();
        for (int i=0;i<max_row;++i)
        {
            for (int j=0;j<max_col;++j)
            {
                if(m_board[i][j]==m_word[0]){
                    memset(visited,0,sizeof(visited));
                    visited[i][j]=true;
                    dfs(1,i,j);
                    if(res)
                        return true;
                    else{
                        visited[i][j]=false;
                        continue;
                    }
                }
            }
        }
        return false;
    }
};

int main()
{
    freopen("C:\\Users\\Administrator\\Desktop\\a.txt","r",stdin);
    vector<char> a;a.push_back(‘A‘);a.push_back(‘B‘);a.push_back(‘C‘);a.push_back(‘F‘);
    vector<char> b;b.push_back(‘W‘);b.push_back(‘G‘);b.push_back(‘C‘);b.push_back(‘G‘);
    vector<char> c;c.push_back(‘B‘);c.push_back(‘A‘);c.push_back(‘F‘);c.push_back(‘Q‘);
    vector<vector<char>> d;
    d.push_back(a);d.push_back(b);d.push_back(c);
    Solution so;
    cout<<so.exist(d,"ABCCF")<<endl;
    cout<<so.exist(d,"FGQ")<<endl;
    cout<<so.exist(d,"ABCCGQFAG")<<endl;
    return 0;
}
时间: 2024-10-09 02:24:13

Word Search(深度搜索DFS,参考)的相关文章

[LeetCode OJ] Word Search 深度优先搜索DFS

Given a 2D board and a word, find if the word exists in the grid. The word can be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighboring. The same letter cell may not be us

LeetCode 0079. Word Search单词搜索【Python】

LeetCode 0079. Word Search单词搜索[Medium][Python][DFS] Problem LeetCode Given a 2D board and a word, find if the word exists in the grid. The word can be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horiz

lintcode 中等题:word search 单词搜索

题目 单词搜索 给出一个二维的字母板和一个单词,寻找字母板网格中是否存在这个单词. 单词可以由按顺序的相邻单元的字母组成,其中相邻单元指的是水平或者垂直方向相邻.每个单元中的字母最多只能使用一次. 样例 给出board = [ "ABCE", "SFCS", "ADEE" ] word = "ABCCED", ->返回 true, word = "SEE",-> 返回 true, word = 

深度搜索DFS!

好的,接下来就是本萌新的第一篇博客啦.直接上深搜!深度优先搜索(Depth-First-Search),简称“深搜”(dfs),是我们蒟蒻们最基本的搜索操作之一.简单地说,深搜就是递归.下面是抄来的解释:深度优先搜索用一个数组存放产生的所有状态.(1) 把初始状态放入数组中,设为当前状态:(2) 扩展当前的状态,产生一个新的状态放入数组中,同时把新产生的状态设为当前状态:(3) 判断当前状态是否和前面的重复,如果重复则回到上一个状态,产生它的另一状态:(4) 判断当前状态是否为目标状态,如果是目

[LeetCode] Word Search 词语搜索

Given a 2D board and a word, find if the word exists in the grid. The word can be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighboring. The same letter cell may not be us

HDU 4597(记忆化搜索 dfs 参考)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4597 Problem Description Alice and Bob are playing a game. There are two piles of cards. There are N cards in each pile, and each card has a score. They take turns to pick up the top or bottom card from

迷宫(深度搜索dfs)

首先输入一个迷宫,用0,1表示,如:m行n列的迷宫 5 4 0 0 1 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 1 0表示通路,1表示障碍. 然后输入起始点的坐标和终止点的坐标,求从起点到终点最少的步数. 用dfs,代码如下: <span style="font-size:18px;">#include<stdio.h> int book[51][51],p[51][51]; int min=99999,endx,endy;//因为终点坐

[C++]LeetCode: 97 Word Search (深度优先搜索)

题目: Given a 2D board and a word, find if the word exists in the grid. The word can be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighboring. The same letter cell may not b

(Java) LeetCode 79. Word Search —— 单词搜索

Given a 2D board and a word, find if the word exists in the grid. The word can be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighboring. The same letter cell may not be us