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;
}
}
};