《剑指Offer》-68-二叉树的最近公共祖先
二叉搜索树
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) { // 如果p、q一定存在,那么root就一定不是空指针 TreeNode* traverse = root; while (true) { if (p->val < traverse->val && q->val < traverse->val) traverse = traverse->left; else if (p->val > traverse->val && q->val > traverse->val) traverse = traverse->right; else if (p == traverse) return p; else if (q == traverse) return q; else return traverse; } }
二叉树
递归自底向上,返回每一个节点下面(包括)自己有没有目标节点之一
- 有就返回子节点指针(最开始肯定是返回自己的指针)
- 没有就返回空指针
- 左右节点都各自包含一个就找到了
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) { if (!root) return nullptr; TreeNode* leftHas = lowestCommonAncestor(root->left, p, q); TreeNode* rightHas = lowestCommonAncestor(root->right, p, q); if ((leftHas && rightHas) || root == p || root == q) return root; if (leftHas) return leftHas; else return rightHas; }
任意树
由于 力扣 平台本身的限制,书中的最后一问没有体现出来——对于任意树
书中给出的思路是这样的:
- 遍历整棵树并构造出两条从根节点到目标节点的链表
- 查找链表的最后一个公共节点
对于 1 可以采用一种回溯的做法,另外就是这里不需要真的去构建一条链表,因为其实是从已经一一指向的路径中挑选一条就可以了,所以其实用数组也是可以的
对于 2 很简单,双指针
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) { vector<TreeNode*> list1, list2; findPath(list1, p,root); findPath(list2, q,root); TreeNode* res = nullptr; for (int i = 0; i < min(list1.size(), list2.size()); i++) { if (list1[i] == list2[i]) res = list1[i]; else break; } return res; } bool findPath(vector<TreeNode*> &list, TreeNode* target,TreeNode* root) { if (!root) return false; list.push_back(root); if (list.back() == target) return true; if (findPath(list, target, root->left) || findPath(list, target, root->right)) { return true; } list.pop_back(); return false; }
本文作者:YaosGHC
本文链接:https://www.cnblogs.com/yaocy/p/17676586.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
2022-09-04 剑指Offer-49-丑数/力扣-264-丑数-Ⅱ