Given a 2D board and a list of words from the dictionary, find all words in the board.
Each word must is constructed from letters of sequentially adjacent cell, where "adjacent" cells is those horizontally or Vertically neighboring. The same letter cell is used more than once in a word.
For example,
Given words = and ["oath","pea","eat","rain"]
board =
[ [' O ', ' a ', ' a ', ' n '], [' e ', ' t ', ' a ', ' e '], [' I ', ' h ', ' K ', ' R '], [' I ', ' f ', ' l ', ' V ']]
Return ["eat","oath"]
.
A. Analogy of ideas
In Word search:http://www.cnblogs.com/zengzy/p/4941110.html, a word that Word searches in board for a time complexity of O (m*n*m*n), If there is a K word then the time complexity is O (k*m*n*m*n). So, is it better to optimize a little bit of the way? When we compare word Search2 with 1, we find that WS2 (Word Search2) has a K-word, and WS1 has only one word, so we want a structure that can organize k-words, So that we can find a word in k words just like in a single word, in other words, we want to find a word in the K-word time cost is O (word_length). This structure can be done by borrowing a tree + hash, where each letter of the word is a node in the tree, and the next letter is the next node of the node, which can be stored in a hash table, which is also called a dictionary tree or a key tree.
Two. Complexity of time
As already described above, although there are k words, but its external performance is like only one word, so the time complexity is O (m*n*m*n).
Three. Complexity of space
In this problem, the nodes ' sub-nodes can be represented by an array of size 26, which is the 26-fork Tree:
struct node{
Char c;//node value
bool Isword; Is this node the end of a word?
struct node* children[26];
}
The height of the tree is the longest word length, set to Len, then the space complexity is O (26^0+26^2+...+26^len)
Four. Code, note that there is a memory leak in the code, because the destructor does not release memory after new.
classTree;classsolution;classnode{ Public: FriendclassTree; Friendclasssolution;Private: Char_c; BOOL_isword; Vector<Node*>_children; Public: Node (CharCBOOLisword=false, size_t children_size=0): _c (c), _isword (Isword), _children (children_size,null) {}BOOLGetisword () {return_isword; }};classtree{Private: Node*_root; Public: Tree (Node* root=NULL) {_root=Root; } voidInsertConst string&insert_str) {size_t insert_str_size=insert_str.size (); Node* cur =_root; for(size_t i=0; i<insert_str_size;i++){ if(cur->_children[insert_str[i]-'a']==NULL) {Node*node =NewNode (Insert_str[i),false, -); Cur->_children[insert_str[i]-'a']=node; Cur=node; }Else{cur= cur->_children[insert_str[i]-'a']; }} cur->_isword =true; } Node*Getroot () {return_root; }};classSolution { Public: voidDFS (vector<vector<Char>>& board,vector<vector<BOOL>>& visited,unordered_set<string>& sets,string& Str,node* Node,intRowintColintCur_r,intcur_c) { if(cur_r<0|| Cur_r>=row | | cur_c<0|| Cur_c>=col | |Visited[cur_r][cur_c]) { return ; } Visited[cur_r][cur_c]=true; Charc =Board[cur_r][cur_c]; Str.push_back (c); Node* Child = node->_children[c-'a']; if(Child! =NULL) { if(child->Getisword ()) Sets.insert (str); DFS (Board,visited,sets,str,child,row,col,cur_r-1, Cur_c); DFS (Board,visited,sets,str,child,row,col,cur_r,cur_c+1); DFS (Board,visited,sets,str,child,row,col,cur_r+1, Cur_c); DFS (Board,visited,sets,str,child,row,col,cur_r,cur_c-1); } Visited[cur_r][cur_c]=false; Str.pop_back (); } Vector<string> Findwords (vector<vector<Char>>& board, vector<string>&words) {Vector<string>Res; if(Board.empty ()) {returnRes; } Tree Root (NewNode ('#',false, -)); for(size_t i=0; I<words.size (); i++) {Root.insert (words[i]); } introw =board.size (); intCol = board[0].size (); Vector<vector<BOOL>> visited (row,vector<BOOL> (col,false)); stringstr; Unordered_set<string>sets; for(size_t i=0; i<row;i++){ for(size_t j=0; j<col;j++) {DFS (Board,visited,sets,str,root.getroot (), row,col,i,j); } } for(Auto iter = Sets.begin (); Iter!=sets.end (); iter++) {Res.push_back (*ITER); } returnRes; }};
Word Search II