212. Word Search II
阿新 • • 發佈:2021-01-11
問題:
給定一個字母表,求給定的單片語中,能夠在字母表中找到的單詞。(相鄰兩個字母,上下左右連續)
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 };