zoukankan      html  css  js  c++  java
  • [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 used more than once.

    For example,
    Given board =

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

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

    典型的搜索问题,这道题目用了两种方法来做。

    一种用到动态规划的思想,用一个vector记录下word中前i个字符构成的子串的所有搜索路径,然后对于前i+1个字符构成的子串

    查找搜索路径时,只需判断第i+1个字符在当前由前i个字符构成的子串的搜索路径的最后一个位置的上下左右四个方向是否出现,

    如果出现则保存新的路径。最后只需判断查找word时是否有可行的搜索路径存在,如果有,则返回true,否则,返回false。但是,

    这种方法的复杂度很高,对于大的测试数据,出现TLE。

     1 class Solution {
     2 public:
     3     bool exist(vector<vector<char> > &board, string word) {
     4         map<int, vector<vector<unsigned> > > path;  //path[i]表示word中的前i个字符构成的字符串在board中的查找路径,一共有path[i].size()条合法查找路径
     5         if(word.size()==0)
     6             return true;
     7         int width = board[0].size();
     8         for(unsigned i=0; i<board.size()*width; i++)
     9         {
    10             if(board[i/width][i%width]==word[0])
    11             {
    12                 vector<unsigned> start;
    13                 start.push_back(i);
    14                 path[1].push_back(start);
    15             }
    16         }
    17         for(unsigned i=1; i<word.size(); i++)
    18         {
    19             char c = word[i];
    20             //vector<vector<unsigned> > pt = path[i-1];
    21 
    22             for(vector<vector<unsigned> >::iterator it=path[i].begin(); it!=path[i].end(); it++)
    23             {
    24                 vector<unsigned> unipath = *it;
    25 
    26                 int lastpos = unipath.back();
    27 
    28                 if((lastpos-width)>=0 && board[(lastpos-width)/width][(lastpos-width)%width]==c && find(unipath.begin(), unipath.end(), (lastpos-width))==unipath.end())
    29                 {
    30                     unipath.push_back(lastpos-width);
    31                     path[i+1].push_back(unipath);
    32                     unipath.pop_back();
    33                 }
    34                 if((lastpos+width)<(board.size()*width) && board[(lastpos+width)/width][(lastpos+width)%width]==c && find(unipath.begin(), unipath.end(), (lastpos+width))==unipath.end())
    35                 {
    36                     unipath.push_back(lastpos+width);
    37                     path[i+1].push_back(unipath);
    38                     unipath.pop_back();
    39                 }
    40                 if(lastpos%width>0 && board[(lastpos-1)/width][(lastpos-1)%width]==c && find(unipath.begin(), unipath.end(), (lastpos-1))==unipath.end())
    41                 {
    42                     unipath.push_back(lastpos-1);
    43                     path[i+1].push_back(unipath);
    44                     unipath.pop_back();
    45                 }
    46                 if((lastpos%width)<(width-1) && board[(lastpos+1)/width][(lastpos+1)%width]==c && find(unipath.begin(), unipath.end(), (lastpos+1))==unipath.end())
    47                 {
    48                     unipath.push_back(lastpos+1);
    49                     path[i+1].push_back(unipath);
    50                     unipath.pop_back();
    51                 }
    52                 if(i==word.size()-1 && path[word.size()].size()!=0)
    53                     return true;
    54             }
    55         }
    56         if(path[word.size()].size()==0)
    57             return false;
    58         else
    59             return true;
    60     }
    61 };

    第二种是用到DFS(深度优先搜索),先找到可行的起始点,然后对于每个起始点判断是否有一条合法搜索路径存在,如果找到

    一条合法搜索路径,则不进行后续搜索,直接返回true。如果所有可能的路径验证都不成立后,最后返回false。测试AC。

     1 void search(vector<vector<char> > &board, string word, vector<int> &path, bool &flag)
     2 {
     3     if(word.size()==0)
     4     {
     5         flag = true;
     6         return;
     7     }
     8 
     9     int width = board[0].size();
    10     char c = word[0];
    11     if(path.size()==0)
    12     {
    13         for(unsigned i=0; i<board.size()*width; i++)
    14         {
    15             if(board[i/width][i%width]==c)
    16             {
    17                 path.push_back(i);
    18                 search(board, word.substr(1), path, flag);
    19                 if(flag==true)
    20                     return;
    21                 path.pop_back();
    22             }
    23         }
    24     }
    25     else
    26     {
    27         int lastpos = path.back();
    28         if((lastpos-width)>=0 && board[(lastpos-width)/width][(lastpos-width)%width]==c && find(path.begin(), path.end(), (lastpos-width))==path.end())
    29         {
    30             path.push_back(lastpos-width);
    31             search(board, word.substr(1), path, flag);
    32             if(flag==true)
    33                 return;
    34             path.pop_back();
    35         }
    36         if((lastpos+width)<(board.size()*width) && board[(lastpos+width)/width][(lastpos+width)%width]==c && find(path.begin(), path.end(), (lastpos+width))==path.end())
    37         {
    38             path.push_back(lastpos+width);
    39             search(board, word.substr(1), path, flag);
    40             if(flag==true)
    41                 return;
    42             path.pop_back();
    43         }
    44         if(lastpos%width>0 && board[(lastpos-1)/width][(lastpos-1)%width]==c && find(path.begin(), path.end(), (lastpos-1))==path.end())
    45         {
    46             path.push_back(lastpos-1);
    47             search(board, word.substr(1), path, flag);
    48             if(flag==true)
    49                 return;
    50             path.pop_back();
    51         }
    52         if((lastpos%width)<(width-1) && board[(lastpos+1)/width][(lastpos+1)%width]==c && find(path.begin(), path.end(), (lastpos+1))==path.end())
    53         {
    54             path.push_back(lastpos+1);
    55             search(board, word.substr(1), path, flag);
    56             if(flag==true)
    57                 return;
    58             path.pop_back();
    59         }
    60 
    61     }
    62 
    63 }
    64 
    65 class Solution {
    66 public:
    67     bool exist(vector<vector<char> > &board, string word) {
    68         bool flag = false;
    69         vector<int> path;
    70 
    71         search(board, word, path, flag);
    72 
    73         return flag;
    74     }
    75 };
  • 相关阅读:
    TCP 登录实现代码
    网络编程步骤 乔老师整理
    网络编程步骤 乔老师整理
    UDP 编程 客服咨询回复
    UDP 编程 客服咨询回复
    利用java在服务器和客服端建立连接,进行通讯(代码实例)
    利用java在服务器和客服端建立连接,进行通讯(代码实例)
    InetAddress 类简介
    InetAddress 类简介
    Mysql并发时经典常见的死锁原因及解决方法
  • 原文地址:https://www.cnblogs.com/Marrybe/p/3853224.html
Copyright © 2011-2022 走看看