leetcode树(235、236、865、1123、1026公共祖先)

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);
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值