212. Word Search II
问题:
给定一个字母表,求给定的单词组中,能够在字母表中找到的单词。(相邻两个字母,上下左右连续)
Example 1: Input: board = [["o","a","a","n"],["e","t","a","e"],["i","h","k","r"],["i","f","l","v"]], words = ["oath","pea","eat","rain"] Output: ["eat","oath"] Example 2: Input: board = [["a","b"],["c","d"]], words = ["abcb"] Output: [] Constraints: m == board.length n == board[i].length 1 <= m, n <= 12 board[i][j] is a lowercase English letter. 1 <= words.length <= 3 * 104 1 <= words[i].length <= 10 words[i] consists of lowercase English letters. All the strings of words are unique.
解法:Backtracking(回溯算法)
- path:该单词,目前为止匹配到的字母处。
- optlists:从字母表当前位置,上下左右下一个位置选择的字母。
⚠️ 注意:由于本问题上下左右皆可移动,有可能出现走过的cell,又被走到,因此需要将做过的cell标记为“#”
- 初始化操作:
- 拿着每一个待check的单词,在字母表中进行尝试。
- 对于每个单词,都要从字母表的每个cell开始进行尝试。
- 结束条件:
- 找到这个单词(找到最后一个字母),将该单词加入res。
- 上下左右都没有下一个字母,没找到这个单词,返回即可。
♻️ 优化:为偏移遍历待选择的各单词,建立数据结构WordPath。
每个单词的各个字符迁移,通过链表next指针链接,到达最后一个字符,将该单词(整个path)保存在string word中。
代码参考:
1 class WordPath { 2 public: 3 string word; 4 vector<WordPath*> next; 5 WordPath() { 6 next = vector<WordPath*>(26, NULL); 7 } 8 }; 9 class Solution { 10 public: 11 WordPath createWP(vector<string>& words) { 12 WordPath root; 13 WordPath* p; 14 for(string word:words) { 15 p = &root; 16 for(char w:word) { 17 if(!p->next[w-'a']) p->next[w-'a'] = new WordPath(); 18 p = p->next[w-'a']; 19 } 20 p->word = word; 21 } 22 return root; 23 } 24 void DFS(vector<string>& res, vector<vector<char>>& board, int i, int j, WordPath* p) { 25 char c = board[i][j]; 26 if(c=='#' || !p->next[c-'a']) return;//'#':visited 27 p=p->next[c-'a']; 28 if(p->word.length()>0) { 29 res.push_back(p->word); 30 p->word.clear(); 31 } 32 board[i][j] = '#'; 33 if(i < board.size()-1) DFS(res, board, i+1, j, p); 34 if(j < board[0].size()-1) DFS(res, board, i, j+1, p); 35 if(i > 0) DFS(res, board, i-1, j, p); 36 if(j > 0) DFS(res, board, i, j-1, p); 37 board[i][j] = c; 38 return; 39 } 40 vector<string> findWords(vector<vector<char>>& board, vector<string>& words) { 41 WordPath root = createWP(words); 42 vector<string> res; 43 for(int i=0; i<board.size(); i++) { 44 for(int j=0; j<board[0].size(); j++) { 45 DFS(res, board, i, j, &root); 46 } 47 } 48 return res; 49 } 50 };