程序员面试金典 4.6

Successor:查找二叉搜索树中一个给定节点的中序遍历后续节点。

书上还有另外一个假设,就是假设每个节点有指向其父节点的指针,因此实现了一个递归解法。根据中序遍历的性质:

  • 如果该节点有右子树,则后继节点就是右子树的最左子节点
  • 如果该节点没有右子树,但是父节点的左子树,则后继节点是父节点
  • 如果不是上面两种情况,则后继节点就是中序遍历的下一个节点,可以通过父节点指针一直向上回溯,直到回溯到某一节点时,该节点是其父节点的左子树。

但是力扣上不存在父节点指针域,所以有两种办法,一种是中序遍历二叉树,找到p时立个flag,则下一个被访问的节点就是后继节点,写起来很丑陋。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
private:
    bool flag = false;
public:
    TreeNode* inorderSuccessor(TreeNode* root, TreeNode* p) {
        if(root == nullptr) return nullptr;
        TreeNode* ret = inorderSuccessor(root->left, p);
        if(ret != nullptr) return ret;
        if(root == p) flag = true;
        else if(flag){
            ret = root;
            flag = false;
            return ret;
        }
        return inorderSuccessor(root->right, p);
    }
};

另一种办法是利用p->val。如果大于等于根,就在右子树中找;如果小于根,就在左子树中找,如果左子树没找到,则就是根。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode* inorderSuccessor(TreeNode* root, TreeNode* p) {
        if(root == nullptr) return nullptr;
        if(p->val >= root->val){
            return inorderSuccessor(root->right, p);
        }
        else{
            TreeNode* ret = inorderSuccessor(root->left, p);
            if(ret != nullptr) return ret;
            else return root;
        }
    }
};
发布了194 篇原创文章 · 获赞 2 · 访问量 7733

猜你喜欢

转载自blog.csdn.net/RayoNicks/article/details/105319691
4.6