diff --git a/leetcode/DIRECTORY.md b/leetcode/DIRECTORY.md index 06e426fe..a2914f1e 100644 --- a/leetcode/DIRECTORY.md +++ b/leetcode/DIRECTORY.md @@ -66,6 +66,7 @@ | 230 | [Kth Smallest Element in a BST](https://leetcode.com/problems/kth-smallest-element-in-a-bst/) | [C](./src/230.c) | Medium | | 231 | [Power of Two](https://leetcode.com/problems/power-of-two/) | [C](./src/231.c) | Easy | | 234 | [Palindrome Linked List](https://leetcode.com/problems/palindrome-linked-list/) | [C](./src/234.c) | Easy | +| 236 | [Lowest Common Ancestor of a Binary Tree](https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/) | [C](./src/236.c) | Medium | | 242 | [Valid Anagram](https://leetcode.com/problems/valid-anagram/) | [C](./src/242.c) | Easy | | 268 | [Missing Number](https://leetcode.com/problems/missing-number/) | [C](./src/268.c) | Easy | | 278 | [First Bad Version](https://leetcode.com/problems/first-bad-version/) | [C](./src/278.c) | Easy | diff --git a/leetcode/src/236.c b/leetcode/src/236.c new file mode 100644 index 00000000..71235c4e --- /dev/null +++ b/leetcode/src/236.c @@ -0,0 +1,82 @@ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * struct TreeNode *left; + * struct TreeNode *right; + * }; + */ + +// The list for TreeNodes. +struct ListItem { + struct TreeNode* node; // TreeNode pointer + struct ListItem* next; // Pointer to the next ListItem +}; + +bool findTargetPath(struct TreeNode* node, struct TreeNode* target, struct ListItem* path){ + if (node == NULL){ + return false; + } + + struct ListItem* pathItem = malloc(sizeof(struct ListItem)); + pathItem->node = node; + pathItem->next = NULL; + path->next = pathItem; + + if (node->val == target->val){ + return true; + } + + if (findTargetPath(node->left, target, pathItem)){ + return true; + } + + if (findTargetPath(node->right, target, pathItem)){ + return true; + } + + path->next = NULL; + free(pathItem); + return false; +} + +void freeList(struct ListItem* target){ + if (target->next != NULL){ + freeList(target->next); + } + + free(target); +} + + +// Find full path for p and q. +// Find the longest common path in paths. + +// Runtime: O(n) +// Space: O(n) +struct TreeNode* lowestCommonAncestor(struct TreeNode* root, struct TreeNode* p, struct TreeNode* q) { + struct ListItem* pPath = malloc(sizeof(struct ListItem)); + struct ListItem* qPath = malloc(sizeof(struct ListItem)); + + findTargetPath(root, p, pPath); + findTargetPath(root, q, qPath); + + struct TreeNode* lowestTreeNode = NULL; + struct ListItem* pPathCursor = pPath->next; + struct ListItem* qPathCursor = qPath->next; + while(pPathCursor != NULL && qPathCursor != NULL) { + if (pPathCursor->node->val == qPathCursor->node->val){ + lowestTreeNode = pPathCursor->node; + pPathCursor = pPathCursor->next; + qPathCursor = qPathCursor->next; + continue; + } + + break; + } + + freeList(pPath); + freeList(qPath); + + return lowestTreeNode; +}