| 
 | 1 | +struct TrieNode {  | 
 | 2 | +	TrieNode* children[26];  | 
 | 3 | +	int wordEndCnt;  | 
 | 4 | +	string word;  | 
 | 5 | + | 
 | 6 | +	TrieNode() : wordEndCnt(0), word("") {  | 
 | 7 | +		for (int i = 0; i < 26; ++i)  | 
 | 8 | +			children[i] = nullptr;  | 
 | 9 | +	}  | 
 | 10 | +};  | 
 | 11 | + | 
 | 12 | +class Solution {  | 
 | 13 | +public:  | 
 | 14 | +	void addWord(TrieNode* node, const string& word) {  | 
 | 15 | +		// simple trie insertion  | 
 | 16 | +		TrieNode* cur = node;  | 
 | 17 | + | 
 | 18 | +		int idx;  | 
 | 19 | +		for (int i = 0; i < word.size(); ++i) {  | 
 | 20 | +			idx = word[i] - 'a';  | 
 | 21 | +			if (cur->children[idx] == nullptr)  | 
 | 22 | +				cur->children[idx] = new TrieNode;  | 
 | 23 | +			cur = cur->children[idx];  | 
 | 24 | +		}  | 
 | 25 | +		// increase the word end counter  | 
 | 26 | +		++cur->wordEndCnt;  | 
 | 27 | +		cur->word = word;  | 
 | 28 | +	}  | 
 | 29 | + | 
 | 30 | +	void solve(vector<vector<char>>& board, int ROWS, int COLS, int r, int c, vector<string>& result, TrieNode* cur) {  | 
 | 31 | +		// boundary check  | 
 | 32 | +		if (r < 0 || r >= ROWS || c < 0 || c >= COLS)  | 
 | 33 | +			return;  | 
 | 34 | +		// visit check  | 
 | 35 | +		if (board[r][c] == '$')  | 
 | 36 | +			return;  | 
 | 37 | +		// existence check   | 
 | 38 | +		int idx = board[r][c] - 'a';  | 
 | 39 | +		if (cur->children[idx] == nullptr)  | 
 | 40 | +			return;  | 
 | 41 | +		cur = cur->children[idx];  | 
 | 42 | +		if (cur->wordEndCnt > 0) {  | 
 | 43 | +			// found word  | 
 | 44 | +			result.push_back(cur->word);  | 
 | 45 | +			--cur->wordEndCnt;  | 
 | 46 | +		}  | 
 | 47 | + | 
 | 48 | +		// mark as visited and backtrack  | 
 | 49 | +		char origin = board[r][c];  | 
 | 50 | +		board[r][c] = '$';  | 
 | 51 | +		solve(board, ROWS, COLS, r + 1, c, result, cur);  | 
 | 52 | +		solve(board, ROWS, COLS, r - 1, c, result, cur);  | 
 | 53 | +		solve(board, ROWS, COLS, r, c + 1, result, cur);  | 
 | 54 | +		solve(board, ROWS, COLS, r, c - 1, result, cur);  | 
 | 55 | +		board[r][c] = origin;  | 
 | 56 | +	}  | 
 | 57 | + | 
 | 58 | +	vector<string> findWords(vector<vector<char>>& board, vector<string>& words) {  | 
 | 59 | +		TrieNode* root = new TrieNode;  | 
 | 60 | +		for (auto w : words) {  | 
 | 61 | +			addWord(root, w);  | 
 | 62 | +		}  | 
 | 63 | +		int ROWS = board.size(), COLS = board[0].size();  | 
 | 64 | + | 
 | 65 | +		vector<string> result;  | 
 | 66 | +		// check every cells  | 
 | 67 | +		for (int i = 0; i < ROWS; ++i)  | 
 | 68 | +			for (int j = 0; j < COLS; ++j)  | 
 | 69 | +				solve(board, ROWS, COLS, i, j, result, root);  | 
 | 70 | +		return result;  | 
 | 71 | +	}  | 
 | 72 | +};  | 
0 commit comments