leetcode212 单词搜索

单词搜索的高级形式,在同一个矩阵中搜索多个单词。因为刚刚完成了tire也就是前缀树的撰写,整体写起来并不困难,使用深度优先搜索的递归就可以。然而问题出在效率上,尤其是所需要进行搜索的单词数量比较多的时候。进行了一些方面的修改。第一点是在完成一个单词的搜索之后就将该单词对应node的isend标志修改为false,防止出现同样的单词被搜索两次的情况。第二个问题是在递归的过程中,dfs函数可以加上一个node参数,代表上一个字符所对应的节点,所以在递归过程中不需要苦大仇深的去调用判断是否为前缀的函数,只需要判断当前搜索到的字符是否是这个节点的某一子节点,若是子节点了,那判断是不是某一单词的结尾,这样就省去了调用函数的消耗。第三点,可以在某一字符串结尾处的节点加上一个string类型的变量,这样若是判断该节点搜索到了某一单词,就直接将该节点的这一变量送上去,而不需要在dfs中增加一个string类型的变量以指示当前的字符串。修改完这三个问题,效率就有较大的提升。贴代码

  1 //前缀树
  2 class Trie {
  3 public:
  4     string word;
  5     vector<Trie*> children;
  6     bool isEnd;
  7 
  8     /** Initialize your data structure here. */
  9     Trie():children(26),isEnd(false){}
 10     
 11     /** Inserts a word into the trie. */
 12     void insert(string word) 
 13     {
 14         Trie* node = this;
 15         for(auto temp:word)
 16         {
 17             temp -= 'a';
 18             if(node->children[temp] == nullptr)
 19             {
 20                 node->children[temp] = new Trie();
 21             }
 22             node = node->children[temp];
 23         }
 24         node->isEnd = true;
 25         node->word = word;
 26     }
 27     
 28     /** Returns if the word is in the trie. */
 29     bool search(string word) 
 30     {
 31         Trie* node = this;
 32         for(auto temp:word)
 33         {
 34             temp -= 'a';
 35             if(node->children[temp] != nullptr)
 36             node = node->children[temp];
 37             else
 38             return false;
 39         }
 40         if(node->isEnd)
 41         return true;
 42         else
 43         return false;        
 44     }
 45     
 46     /** Returns if there is any word in the trie that starts with the given prefix. */
 47     bool startsWith(string prefix) 
 48     {
 49         Trie* node = this;
 50         for(auto temp:prefix)
 51         {
 52             temp -= 'a';
 53             if(node->children[temp] != nullptr)
 54             node = node->children[temp];
 55             else
 56             return false;
 57         }
 58         return true;
 59     }
 60 
 61     bool deleteWord(string word)
 62     {
 63         if(this->search(word))
 64         {
 65             Trie* node = this;
 66             for(auto temp:word)
 67             {
 68                 temp -= 'a';
 69                 if(node->children[temp] != nullptr)
 70                 node = node->children[temp];
 71                 else
 72                 return false;
 73             }
 74             node->isEnd = false;
 75             return true;
 76         }
 77         return false;
 78     }
 79 };
 80 class Solution {
 81 public:
 82     Trie* root;
 83     int m;
 84     int n; 
 85     vector<string> res;   
 86     vector<string> findWords(vector<vector<char>>& board, vector<string>& words) 
 87     {
 88         root = new Trie();
 89         for(auto word:words)
 90         root->insert(word);
 91         m = board.size();
 92         n = board[0].size();
 93         set<string> ans;
 94         for(int i = 0 ; i < m ; i++)
 95         {
 96             for(int j = 0 ; j < n ; j++)
 97             {
 98                 string temp;
 99                 temp.push_back(board[i][j]);
100                 if(root->startsWith(temp))
101                 dfs(board,i,j,root);             
102             }
103         }
104         return res;
105     }
106     void dfs(vector<vector<char>>& board,int i,int j,Trie* node)
107     {
108         char t = board[i][j];
109         int p = t-'a';
110         board[i][j] = '0';
111         if(node->children[p]!=nullptr && node->children[p]->isEnd)
112         {
113             res.push_back(node->children[p]->word);
114             node->children[p]->isEnd = false;
115         }
116         if(node->children[p]!=nullptr)
117         {
118             node = node->children[p];
119             if(i+1<m && board[i+1][j] != '0')
120             dfs(board,i+1,j,node);
121             if(i-1>=0 && board[i-1][j] != '0')
122             dfs(board,i-1,j,node);
123             if(j+1<n && board[i][j+1] != '0')
124             dfs(board,i,j+1,node);
125             if(j-1>=0 && board[i][j-1] != '0')
126             dfs(board,i,j-1,node);
127         }
128         board[i][j] = t;        
129     }
130 
131 };

 

posted @ 2021-09-17 19:27  zhaohhhh  阅读(38)  评论(0)    收藏  举报