編程練習題:找到二叉數中某兩個節點的第一個共同祖先節點

找到二叉數中某兩個節點的第一個共同祖先節點。這裏給出了兩種解法,分別是常規解法和遞歸解法。
常規解法:首先從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
        }
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章