1. 程式人生 > 實用技巧 >212. Word Search II

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