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 };

浙公网安备 33010602011771号