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

 

posted @ 2021-01-11 15:09  habibah_chang  阅读(88)  评论(0编辑  收藏  举报