Given a 2D board and a list of words from the dictionary, find all words in the board.
Each word must be constructed from letters of sequentially adjacent cell, where “adjacent” cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once in a word.
Example:
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"]
Note:
- All inputs are consist of lowercase letters
a-z
. - The values of
words
are distinct.
Solution 1: DFS
Time complexity: O(sum(m*n*4^l))
Space complexity: O(l)
C++
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
// Author: Huahua, 708 ms, 15.3 MB class Solution { public: vector<string> findWords(vector<vector<char>>& board, vector<string>& words) { unordered_set<string> unique_words(words.begin(), words.end()); vector<string> ans; for (const string& word : unique_words) if (exist(board, word)) ans.push_back(word); return ans; } private: int w; int h; bool exist(vector<vector<char>> &board, string word) { if (board.size() == 0) return false; h = board.size(); w = board[0].size(); for (int i = 0 ; i < w; i++) for (int j = 0 ; j < h; j++) if (search(board, word, 0, i, j)) return true; return false; } bool search(vector<vector<char>> &board, const string& word, int d, int x, int y) { if (x < 0 || x == w || y < 0 || y == h || word[d] != board[y][x]) return false; // Found the last char of the word if (d == word.length() - 1) return true; char cur = board[y][x]; board[y][x] = '#'; bool found = search(board, word, d + 1, x + 1, y) || search(board, word, d + 1, x - 1, y) || search(board, word, d + 1, x, y + 1) || search(board, word, d + 1, x, y - 1); board[y][x] = cur; return found; } }; |
Solution 2: Trie
Store all the words into a trie, search the board using DFS, paths must be in the trie otherwise there is no need to explore.
Time complexity: O(sum(l) + 4^max(l))
space complexity: O(sum(l) + l)
C++
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
// Author: Huahua, 64 ms, 35.6 MB class TrieNode { public: vector<TrieNode*> nodes; const string* word; TrieNode(): nodes(26), word(nullptr) {} ~TrieNode() { for (auto node : nodes) delete node; } }; class Solution { public: vector<string> findWords(vector<vector<char>>& board, vector<string>& words) { TrieNode root; // Add all the words into Trie. for (const string& word : words) { TrieNode* cur = &root; for (char c : word) { auto& next = cur->nodes[c - 'a']; if (!next) next = new TrieNode(); cur = next; } cur->word = &word; } const int n = board.size(); const int m = board[0].size(); vector<string> ans; function<void(int, int, TrieNode*)> walk = [&](int x, int y, TrieNode* node) { if (x < 0 || x == m || y < 0 || y == n || board[y][x] == '#') return; const char cur = board[y][x]; TrieNode* next_node = node->nodes[cur - 'a']; // Pruning, only expend paths that are in the trie. if (!next_node) return; if (next_node->word) { ans.push_back(*next_node->word); next_node->word = nullptr; } board[y][x] = '#'; walk(x + 1, y, next_node); walk(x - 1, y, next_node); walk(x, y + 1, next_node); walk(x, y - 1, next_node); board[y][x] = cur; }; // Try all possible pathes. for (int i = 0 ; i < n; i++) for (int j = 0 ; j < m; j++) walk(j, i, &root); return ans; } }; |
请尊重作者的劳动成果,转载请注明出处!花花保留对文章/视频的所有权利。
如果您喜欢这篇文章/视频,欢迎您捐赠花花。
If you like my articles / videos, donations are welcome.
Be First to Comment