235 二叉搜索树的最近公共祖先
题目描述: 给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。
最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
根据二叉搜索树的性质,找到根节点到两个给定节点的路径,然后遍历比较两个根节点的路径,直到两个节点值不相同,则前一个节点即为其最近公共祖先。如果直到遍历结束,节点值全部相同,则较短路径的最后一个节点即为其最近公共祖先。
class Solution {
public:
void findPath(TreeNode* root, TreeNode* x, vector<TreeNode*>& path) {
path.push_back(root);
if(root -> val == x -> val)
return ;
if(root->val > x->val && root -> left != NULL) {
findPath(root->left, x, path);
// if(flag)
// return true;
// path.pop_back();
}
if(root->val < x->val && root -> right != NULL) {
findPath(root->right, x, path);
// if(flag)
// return true;
// path.pop_back();
}
return ;
}
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
vector<TreeNode*> path1;
vector<TreeNode*> path2;
findPath(root, p, path1);
findPath(root, q, path2);
int m = path1.size(), n = path2.size();
for(int i = 1; i < min(n, m); i++) {
//cout<<path1[i]->val<<" "<<path2[i]->val<<endl;
if(path1[i]->val != path2[i]->val)
return path1[i - 1];
}
if(n < m)
return path2[n - 1];
return path1[m - 1];
}
};
236 二叉树的最近公共祖先
**题目描述:**给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。最近公共祖先定义见上一题。
DFS深度遍历,当遍历的节点为给定节点时,返回true,否则继续向下遍历,或者返回false(当该节点为叶子节点时),当左子树或右子树返回值为false时,pop出路径数组中的最后一个节点。最后得出根节点到指定节点的路径。最后遍历两条找到的路径,求出公共祖先。
class Solution {
public:
bool nodePath(TreeNode* root, TreeNode* p, vector<TreeNode*>& path) {
path.push_back(root);
if(root -> val == p -> val)
return true;
if(root -> left != NULL) {
if(!nodePath(root -> left, p, path))
path.pop_back();
else
return true;
}
if(root -> right != NULL) {
if(!nodePath(root -> right, p, path))
path.pop_back();
else
return true;
}
return false;
}
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
vector<TreeNode*> path1;
vector<TreeNode*> path2;
nodePath(root, p, path1);
nodePath(root, q, path2);
int m = path1.size(), n = path2.size();
for(int i = min(m, n) - 1; i >= 0; i--) {
if(path1[i] ->val == path2[i] ->val)
return path1[i];
}
return path1[0];
}
};
865 具有所有最深结点的最小子树
1123 最深叶节点的最近公共祖先(同865)
题目描述: 给定一个根为 root 的二叉树,每个结点的深度是它到根的最短距离。返回能满足“以该结点为根的子树中包含所有最深的结点”这一条件的具有最大深度的结点。
一次深度优先搜索,返回两个值,分别为包含所有最深节点的最小子树的根节点node,以及所包含的最深节点的深度。对于返回值node,如果其只有一个孩子节点具有最深节点,返回该孩子节点。如果两个孩子都有最深节点,返回node节点本身。
class Solution {
public:
pair<TreeNode*, int> dfs(TreeNode* root, int dep) {
TreeNode* init = NULL;
pair<TreeNode*, int> left = make_pair(init, dep);
pair<TreeNode*, int> right = make_pair(init, dep);
if(root -> left != NULL)
left = dfs(root -> left, dep + 1);
if(root -> right != NULL)
right = dfs(root -> right, dep + 1);
if(left.second > right.second)
return left;
else if(left.second < right.second)
return right;
return make_pair(root, right.second);
}
TreeNode* subtreeWithAllDeepest(TreeNode* root) {
pair<TreeNode*, int> ans = dfs(root, 0);
//cout << ans.second << endl;
return ans.first;
}
};
1026 节点与其祖先之间的最大差值
**题目描述:**给定二叉树的根节点 root,找出存在于不同节点 A 和 B 之间的最大值 V,其中 V = |A.val - B.val|,且 A 是 B 的祖先。
DFS遍历,保存根节点到当前节点路径过程中的最大值和最小值,则V的存在如果包括当前节点,其一定是最大值或最小值与当前节点的差值,更新比较V的最大值即可。
class Solution {
public:
int dfs(TreeNode* root, int min_v, int max_v) {
int ans = 0;
//min_v = min(min_v, root -> val);
//max_v = max(max_v, root -> val);
ans = max(ans, max(abs(min_v - root -> val), abs(max_v - root -> val)));
if(root -> left != NULL) {
ans = max(ans, dfs(root -> left, min(min_v, root -> val), max(max_v, root -> val)));
}
if(root -> right != NULL) {
ans = max(ans, dfs(root -> right, min(min_v, root -> val), max(max_v, root -> val)));
}
return ans;
}
int maxAncestorDiff(TreeNode* root) {
vector<int> node_num;
if(root == NULL)
return 0;
return dfs(root, root -> val, root -> val);
}
};