• LeetCode 212. 单词搜索 II -- 字典树+dfs


    1. 单词搜索 II
      困难
      721
      相关企业
      给定一个 m x n 二维字符网格 board 和一个单词(字符串)列表 words, 返回所有二维网格上的单词 。

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

    示例 1:

    输入:board = [[“o”,“a”,“a”,“n”],[“e”,“t”,“a”,“e”],[“i”,“h”,“k”,“r”],[“i”,“f”,“l”,“v”]], words = [“oath”,“pea”,“eat”,“rain”]
    输出:[“eat”,“oath”]
    示例 2:

    输入:board = [[“a”,“b”],[“c”,“d”]], words = [“abcb”]
    输出:[]

    提示:

    m == board.length
    n == board[i].length
    1 <= m, n <= 12
    board[i][j] 是一个小写英文字母
    1 <= words.length <= 3 * 104
    1 <= words[i].length <= 10
    words[i] 由小写英文字母组成
    words 中的所有字符串互不相同

    题解

    必须要dfs,这是没办法的,数据量这么大,又要DFS,所以可以考虑到要添加一些信息进行约束避免很多无效的搜索,比如,当搜索到某个位置,我们可以判断下一个位置是否可以构成存在于words中的字符串,如果可以构成就继续搜索,不然就停止搜索,如何快速判断当前搜索的字符串是否存在于words呢?

    这个就是字典树的任务了,先把所有的words构建成字典树,不断dfs的时候不断去字典树查询,就很丝滑的通过了。

    字典树 is all you need.

    AC代码

    class Solution {
    public:
        int trie[100000][26] = {0};
        int color[100000] = {0};
        int k = 1;
        void insert(string w){
            int p = 0;
            for(int i=0; i<w.length(); i++){
                int c = w[i] - 'a';
                if(!trie[p][c]){
                    trie[p][c] = k;
                    k++;
                }
                p = trie[p][c];
            }
            color[p]++;
        }
        vector<string>q;
        int xx[4] = {0,0,-1,1};
        int yy[4] = {-1,1,0,0};
        bool vis[15][15] = {false};
        bool count[100000] = {false};
        void dfs(vector<vector<char>>& board, int x, int y, int p, string s)
        {
            int c = board[x][y] - 'a';
            //字典树判断当前字符串是否存在于树中
            if(!trie[p][c])return;
            p = trie[p][c];
            if(color[p]>0&&count[p]==false)
            {
                q.push_back(s);
                //标记是否添加过,避免重复添加
                count[p] = true;
            }
            for(int i=0;i<4;i++)
            {
                int x2 = x + xx[i];
                int y2 = y + yy[i];
                if(x2<0||x2>=board.size()||y2<0||y2>=board[0].size())continue;
                if(vis[x2][y2])continue;
                vis[x2][y2] = true;
                dfs(board, x2, y2, p, s + board[x2][y2]);
                vis[x2][y2] = false;
            }
        }
        vector<string> findWords(vector<vector<char>>& board, vector<string>& words) 
        {
            for(int i=0;i<words.size();i++)
            insert(words[i]);
            for(int i=0;i<board.size();i++)
            {
                for(int j=0;j<board[i].size();j++)
                {
                    string s = "";
                    s += board[i][j];
                    vis[i][j] = true;
                    dfs(board, i, j, 0, s);
                    vis[i][j] = false;
                }
            }
            return q;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
  • 相关阅读:
    每日分享html之2个悬停、2个加载、1个button
    [附源码]java毕业设计静谧空间自习室预订系统
    LQ0152 杨辉三角形【模拟】
    每天学习一个Windows命令或Linux命令——shutdown
    四、RocketMq本地集群搭建
    Python入门-变量定义与切片&Python引入包和引入模块
    OpenGL 着色器使用
    Matlab:多输入多输出非线性对象的模型预测控制(MPC, Model Predictive Control)的实现
    Django 实战开发(一)项目搭建
    1.1 Android 系统概述_智能手机系统介绍
  • 原文地址:https://blog.csdn.net/weixin_43918046/article/details/127771628