• leetcode-79-单词搜索(用dfs解决)


    题目描述:

    给定一个二维网格和一个单词,找出该单词是否存在于网格中。

    单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。

    示例:

    board =
    [
      ['A','B','C','E'],
      ['S','F','C','S'],
      ['A','D','E','E']
    ]
    
    给定 word = "ABCCED", 返回 true.
    给定 word = "SEE", 返回 true.
    给定 word = "ABCB", 返回 false.

     

    要完成的函数:

    bool exist(vector<vector<char>>& board, string word) 

    说明:

    1、这道题给定一个二维的vector,里面存放着多个英文字符,还给了一个string,代表一个英文单词。

    要求判断二维vector中存不存在一条路径,连起来刚好就是string代表的单词。

    这条路径不能使用重复的字符。

    如果存在这样一条路径,那么返回true,不存在就返回false。

    2、这道题其实也就是深度优先搜索(DFS)的题目,熟悉这个算法的同学做这道题会很快。

    我们还是照旧,举个例子,大致说明一下思路。

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

    给定的单词是SEE,那么我们首先在矩阵中找到S,有两个,我们先试第一个,明显第二个字母就对不上了,于是我们进入对第二个的查找。

    在第二个周围,我们先试S上方的E,然后再在这个E的周围找另一个E,明显没有。

    于是我们退一步,不试S上方的E了,我们尝试S下方的E,可以,再在其附近找另一个E,也找得到。

    我们在尝试的时候,要注意这个字符之前有没有使用过,这一步要做点处理。 

    从上述思路中,我们可以知道要用循环+递归的方法来做这道题。

    先用循环找到第一个字符的索引,然后进入递归,如果递归成功找到了,那么返回true。

    如果不存在,那么再循环找第一个字符的下一个索引,然后同样进入递归,如果递归成功了,那么返回true。

    如果还是没有,那么再循环,一直循环,如果一直不满足,最后返回false。

    代码如下(附详解):

        bool dfs(vector<vector<char>>& board,int i,int j,string word,int index)
        {
            if(index==word.size())return true;//退出条件,满足了说明成功找到
            int hang=board.size(),lie=board[0].size();
            if(i>0)//尝试上方的字符
            {
                if(board[i-1][j]==word[index])
                {
                    board[i-1][j]='!';//修改,避免重复使用
                    if(dfs(board,i-1,j,word,index+1))//再度进入递归
                        return true;
                    board[i-1][j]=word[index];//修改回去
                }
            }
            if(i<hang-1)//尝试下方的字符
            {
                if(board[i+1][j]==word[index])
                {
                    board[i+1][j]='!';
                    if(dfs(board,i+1,j,word,index+1))
                        return true;
                    board[i+1][j]=word[index];
                }
            }
            if(j>0)//尝试左边的字符
            {
                if(board[i][j-1]==word[index])
                {
                    board[i][j-1]='!';
                    if(dfs(board,i,j-1,word,index+1))
                        return true;
                    board[i][j-1]=word[index];
                }
            }
            if(j<lie-1)//尝试右边的字符
            {
                if(board[i][j+1]==word[index])
                {
                    board[i][j+1]='!';
                    if(dfs(board,i,j+1,word,index+1))
                        return true;
                    board[i][j+1]=word[index];
                }
            }
            return false;//如果尝试四个方向都没能找到,返回false
        }
        bool exist(vector<vector<char>>& board, string word) 
        {
            int hang=board.size(),lie=board[0].size();
            for(int i=0;i<hang;i++)
            {
                for(int j=0;j<lie;j++)
                {
                    if(board[i][j]==word[0])//找到第一个字符的索引
                    {
                        board[i][j]='!';//修改board中这个索引的值,避免重复使用
                        if(dfs(board,i,j,word,1))//进入递归,如果返回true,那么找得到,最终返回true
                            return true;
                        board[i][j]=word[0];//如果递归没成功找到,那么把索引对应的字符给修改回去
                    }
                }
            }
            return false;//一直没能成功,说明不存在这样一条路径,返回false
        }
    

    上述代码实测20ms,beats 94.50% of cpp submissions。

  • 相关阅读:
    jquery on()方法绑定多个选择器,多个事件
    html中常用的特殊符号(转)
    jQuery自定义动画,animate()包装器方法
    纯CSS下拉菜单
    DIV水平居中的几种方法
    OOXML是什么
    Chrome网络工具总结
    Content-Length错误导致的Servlet下载文件失败问题
    Fiddler操作总结
    WinSCP上传下载过滤指定目录和文件
  • 原文地址:https://www.cnblogs.com/chenjx85/p/9502013.html
Copyright © 2020-2023  润新知