当前位置: 首页 > article >正文

leetcode 212. 单词搜索 II

给定一个 m x n 二维字符网格 board 和一个单词(字符串)列表 words, 返回所有二维网格上的单词 。

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

这里我们需要在字符表中查找words中的单词,如果我们暴力搜索,然后再去检验的化,效率很低,并且每个点都需要搜索所以行不通
这里我们直接建立words的Trie 然后dfs 建立的Trie 大大减少了dfs的范围

Trie节点Trienode 

这里使用map<char,Tirenode*>内存确实效率更好

struct Tirenode
{
   unordered_map<char,Tirenode*> next;
   string s="";                       //标记单词 
};

 Trie节点的添加

 void insert_(string& word)
 {                
     auto node=this->root;     //遍历节点
     for(auto c:word)
     {
         if(!node->next.count(c)) node->next[c]=new Tirenode();  
         node=node->next[c];
     }
     node->s=word; //标记单词
 }

dfs查找

 我们已经将words的单词假如到了Trie结构中
 所以我们只要dfs board中的字符看是否能搜索到temp不为空字符的情况即可
 去重的话如果我们搜索到了单词temp则将它置空,表示我们已经push_back过了 

 void dfs(point p,vector<vector<char>>& board,Tirenode* temp)
    {
        auto [x,y]=p;        //结构化绑定
        char c=board[x][y];  //记录当前字母
        if(!temp->next.count(c)) return;  //搜索到尾了 则退出递归
        
        //搜索到单词
        if(temp->next[c]->s!="") {dp.push_back(temp->next[c]->s);temp->next[c]->s="";};        

        //标记当前单词表示已经搜索
        board[x][y]='#';
        
        //dfs搜索
        for(int i=0;i<4;i++)
        {
            int nx=x+a[i];
            int ny=y+b[i];
            if(nx>=0&&nx<board.size()&&ny>=0&&ny<board[0].size()&&board[nx][ny]!='#')
            {
                dfs({nx,ny},board,temp->next[c]);
            }
        }
        
        //回溯
        board[x][y]=c;
    }

完整代码: 

class Solution {
public:
    typedef pair<int,int> point;
    vector<string> dp;
    int a[4]={0,0,1,-1};
    int b[4]={1,-1,0,0};
    int max_=0;
    struct Tirenode
    {
        unordered_map<char,Tirenode*> next;
        string s="";
    };
    Tirenode* root=new Tirenode();
    void insert_(string& word)
    {
        auto node=this->root;
        for(auto c:word)
        {
            if(!node->next.count(c)) node->next[c]=new Tirenode();
            node=node->next[c];
        }
        node->s=word;
    }
    void dfs(point p,vector<vector<char>>& board,Tirenode* temp)
    {
        auto [x,y]=p;
        char c=board[x][y];
        if(!temp->next.count(c)) return;
        if(temp->next[c]->s!="") {dp.push_back(temp->next[c]->s);temp->next[c]->s="";};
        board[x][y]='#';
        for(int i=0;i<4;i++)
        {
            int nx=x+a[i];
            int ny=y+b[i];
            if(nx>=0&&nx<board.size()&&ny>=0&&ny<board[0].size()&&board[nx][ny]!='#')
            {
                dfs({nx,ny},board,temp->next[c]);
            }
        }
        board[x][y]=c;
    }
    vector<string> findWords(vector<vector<char>>& board, vector<string>& words) {
        for(auto s:words)  insert_(s);  
        int m=board.size();
        int n=board[0].size();
        for(int i=0;i<m;i++)
        {
            for(int j=0;j<n;j++)
            {
                dfs({i,j},board,this->root);
            }
        }
        return dp;
    }
};


http://www.kler.cn/a/409974.html

相关文章:

  • 金融市场和预期
  • RHCSA作业2
  • 第02章_MySQL环境搭建(基础)
  • 秋招面试基础总结,Java八股文基础(串联知识),四万字大全
  • 拉格朗日乘子(Lagrange Multiplier)是数学分析中用于解决带有约束条件的优化问题的一种重要方法,特别是SVM
  • 数据结构-位运算笔记
  • Gitee markdown 使用方法(持续更新)
  • Leetcode647. 回文子串(HOT100)
  • vue项目实现动效交互---lottie动画库
  • Flink中普通API的使用
  • 前端速通(CSS)
  • 力扣 189. 轮转数组
  • C++之《剑指offer》学习记录(12):二叉树的下一个节点
  • node.js路由
  • 香港大带宽服务器:助力高效网络应用
  • 15分钟做完一个小程序,腾讯这个工具有点东西
  • PCB元器件封装和3D库怎么找?
  • springboot/ssm企业车辆管理系统Java企业公交车辆信息管理平台web源码
  • 下载并安装Zsh
  • SD-WAN网络与自动化运维的结合
  • 线性代数在人工智能领域中的实践
  • 原批之星的南邮风云
  • 105.找到冠军
  • Linux中安装InfluxDB
  • 【蓝桥杯C/C++】深入解析I/O高效性能优化:std::ios::sync_with_stdio(false)
  • MQTT.fx连接oneNet中移IOT物联网平台,进行消息的发布的详细步骤