|
| 1 | +typedef struct TrieNode trie_t; |
| 2 | + |
| 3 | +struct TrieNode { |
| 4 | + bool valid; |
| 5 | + char* word; |
| 6 | + int count; |
| 7 | + trie_t* parent; |
| 8 | + trie_t* children[26]; |
| 9 | +}; |
| 10 | + |
| 11 | +void insert(trie_t* root, char* word) { |
| 12 | + char* curr = word; |
| 13 | + while (*curr != '\0') { |
| 14 | + int index = *curr - 'a'; |
| 15 | + if (root->children[index] == NULL) { |
| 16 | + root->children[index] = (trie_t*)calloc(1, sizeof(trie_t)); |
| 17 | + root->children[index]->valid = true; |
| 18 | + root->children[index]->parent = root; |
| 19 | + } |
| 20 | + root->count++; |
| 21 | + root = root->children[index]; |
| 22 | + curr++; |
| 23 | + } |
| 24 | + root->count++; |
| 25 | + root->word = word; |
| 26 | +} |
| 27 | + |
| 28 | +void traverse(char** result, int* resultSize, char** board, bool** visited, int boardSize, int boardColSize, int x, int y, trie_t* node) { |
| 29 | + if (node == NULL || !node->valid) { |
| 30 | + return; |
| 31 | + } |
| 32 | + if (node->word != NULL) { |
| 33 | + result[(*resultSize)++] = node->word; |
| 34 | + node->word = NULL; |
| 35 | + trie_t* curNode = node; |
| 36 | + while (curNode != NULL) { |
| 37 | + curNode->count--; |
| 38 | + if (curNode->count <= 0) { |
| 39 | + curNode->valid = false; |
| 40 | + } |
| 41 | + curNode = curNode->parent; |
| 42 | + } |
| 43 | + } |
| 44 | + visited[x][y] = true; |
| 45 | + |
| 46 | + int directions[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}}; |
| 47 | + for (int i = 0; i < 4; i++) { |
| 48 | + int newX = x + directions[i][0]; |
| 49 | + int newY = y + directions[i][1]; |
| 50 | + if (newX >= 0 && newX < boardSize && newY >= 0 && newY < boardColSize && !visited[newX][newY]) { |
| 51 | + int c = board[newX][newY] - 'a'; |
| 52 | + traverse(result, resultSize, board, visited, boardSize, boardColSize, newX, newY, node->children[c]); |
| 53 | + } |
| 54 | + } |
| 55 | + |
| 56 | + visited[x][y] = false; |
| 57 | +} |
| 58 | + |
| 59 | +char ** findWords(char** board, int boardSize, int* boardColSize, char ** words, int wordsSize, int* returnSize) { |
| 60 | + // Create the trie and insert words |
| 61 | + trie_t* trie = (trie_t*) calloc(1, sizeof(trie_t)); |
| 62 | + for (int i = 0; i < wordsSize; i++) { |
| 63 | + insert(trie, words[i]); |
| 64 | + } |
| 65 | + |
| 66 | + // Allocate memory for the result array |
| 67 | + char** result = (char**) malloc(sizeof(char*) * wordsSize); |
| 68 | + int resultSize = 0; |
| 69 | + |
| 70 | + // Create and initialize the visited array |
| 71 | + bool** visited = (bool**) malloc(sizeof(bool*) * boardSize); |
| 72 | + for (int i = 0; i < boardSize; i++) { |
| 73 | + visited[i] = (bool*) calloc(*boardColSize, sizeof(bool)); |
| 74 | + } |
| 75 | + |
| 76 | + // Traverse the board and find words |
| 77 | + for (int i = 0; i < boardSize; i++) { |
| 78 | + for (int j = 0; j < *boardColSize; j++) { |
| 79 | + int c = board[i][j] - 'a'; |
| 80 | + traverse(result, &resultSize, board, visited, boardSize, *boardColSize, i, j, trie->children[c]); |
| 81 | + } |
| 82 | + } |
| 83 | + |
| 84 | + // Clean up and set the return size |
| 85 | + *returnSize = resultSize; |
| 86 | + return result; |
| 87 | +} |
0 commit comments