编程练习题:找到二叉数中某两个节点的第一个共同祖先节点

找到二叉数中某两个节点的第一个共同祖先节点。这里给出了两种解法,分别是常规解法和递归解法。
常规解法:首先从root开始,自上而下,找到p节点的所有祖先节点,然后依据从下往上的顺序,判断每一个p的祖先节点是不是q的祖先节点,如果是的话,那么就是第一个共同祖先节点,返回

    //判断root是不是q的祖先节点
    bool isancestor(TreeNode *root, TreeNode* q) {
        //root为NULL节点,终止递归,返回
        if (root == NULL) {
            return false;
        }
        //找到q节点,返回True,即root节点是q节点本身,也就是祖先
        if (root->val == q->val) {
            return true;
        } else {
            //如果root的左子树或者右子树是q的祖先结点,那么root也是q的祖先节点
            return isancestor(root->left, q) || isancestor(root->right, q);
        }
    }
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        stack<TreeNode*> nodes;
        TreeNode* node = root;
        //找到p的所有祖先结点,存入nodes
        while (true) {
            //判断node是不是p的祖先节点
            if (isancestor(node, p)) {
                nodes.push(node);
            } else {
                break;
            }
            //递归判断node的左子结点或者右子结点是不是p的祖先,如果是的话,就加入nodes
            if (isancestor(node->left, p)) {
                nodes.push(node->left);
                node = node->left;
            } else if (isancestor(node->right, p)) {
                nodes.push(node->right);
                node = node->right;
            } else {
                break;
            }
        }
        //p结点本身也是祖先结点
        if (node) {
            nodes.push(node);
        }
        //判断p的所有祖先结点,是不是q的祖先结点,如果是,则返回
        while (!nodes.empty()) {
            node = nodes.top();
            nodes.pop();
            if (isancestor(node, q)) {
                return node;
            }
        }
        return NULL;
    }

递归解法:

  struct TreeNode {
	  	 int val;
	  	 TreeNode *left;
	  	 TreeNode *right;
	  	 TreeNode(int x) : val(x), left(NULL), right(NULL) {}
  };
class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        //到达叶子节点,没有找到p节点或者q节点
        if (root == NULL) {
            return NULL;
        }
        //找到了p 节点或者q节点,返回
        if (root->val == p->val || root->val == q->val) {
            return root;
        }
        //在当前节点的左子树和右子树递归寻找p、q节点
        TreeNode *left = lowestCommonAncestor(root->left, p, q);
        TreeNode *right = lowestCommonAncestor(root->right, p, q);
        //p、q节点一个在左子树,一个在右子树,那么共同祖先节点就是当前root节点
        if (left && right) {
            return root;
        //p或q节点都在左子树
        } else if (left) {
            return left;
        //p或q节点都在右子树
        } else if (right) {
            return right;
        } else {
        	return NULL
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值