# Definition for a Node.
# class Node:
# def __init__(self, val, left, right, parent):
# self.val = val
# self.left = left
# self.right = right
# self.parent = parent
class Solution:
def inorderSuccessor(self, node: 'Node') -> 'Node':
if node.right:
# Go to the leftmost node in the right subtree
curr = node.right
while curr.left:
curr = curr.left
return curr
# Go up until we come from left
curr = node
while curr.parent and curr == curr.parent.right:
curr = curr.parent
return curr.parent
/*
Definition for a Node.
class Node {
public:
int val;
Node* left;
Node* right;
Node* parent;
};
*/
class Solution {
public:
Node* inorderSuccessor(Node* node) {
if (node->right) {
Node* curr = node->right;
while (curr->left) {
curr = curr->left;
}
return curr;
}
Node* curr = node;
while (curr->parent && curr == curr->parent->right) {
curr = curr->parent;
}
return curr->parent;
}
};
/*
class Node {
public int val;
public Node left;
public Node right;
public Node parent;
};
*/
class Solution {
public Node inorderSuccessor(Node node) {
if (node.right != null) {
Node curr = node.right;
while (curr.left != null) {
curr = curr.left;
}
return curr;
}
Node curr = node;
while (curr.parent != null && curr == curr.parent.right) {
curr = curr.parent;
}
return curr.parent;
}
}
/**
* // Definition for a Node.
* function Node(val, left, right, parent) {
* this.val = val;
* this.left = left;
* this.right = right;
* this.parent = parent;
* };
*/
/**
* @param {Node} node
* @return {Node}
*/
var inorderSuccessor = function(node) {
if (node.right) {
let curr = node.right;
while (curr.left) {
curr = curr.left;
}
return curr;
}
let curr = node;
while (curr.parent && curr === curr.parent.right) {
curr = curr.parent;
}
return curr.parent;
};
You are given a node node
in a binary search tree (BST). Each node has a parent
pointer in addition to its left
and right
children. Your task is to find the in-order successor of the given node
in the BST.
null
if the given node has no in-order successor.To solve this problem, it's important to recall what an in-order traversal of a BST looks like: it visits nodes in ascending order. The in-order successor of a node is the next node visited after the current node during such a traversal.
The naive approach would be to perform a full in-order traversal of the tree, collect all nodes in a list, and then find the node following the given one. However, this would be inefficient and unnecessary, especially since each node has a parent
pointer, allowing us to move upwards in the tree.
By leveraging the BST properties and the parent
pointer, we can identify two main cases:
right
child, its successor is the leftmost node in its right subtree.
parent
pointer until we find a node that is a left child of its parent; then, its parent is the successor.
This approach is much more efficient and elegant than traversing the entire tree.
right
child of the node.left
child until you can't go further.parent
node repeatedly, as long as the current node is a right child of its parent.null
), then there is no successor.This method efficiently finds the successor in O(h) time, where h is the height of the tree, without needing extra space.
Let's consider the following BST:
5 / \ 3 6 / \ 2 4 / 1
Suppose node = 3
. What is its in-order successor?
node = 4
.
node = 6
:
The optimized approach is efficient both in time and space, especially for balanced BSTs where h = log N.
By leveraging the BST's properties and the presence of a parent
pointer, we can efficiently find the in-order successor of a node without traversing the entire tree. The key insight is to distinguish between nodes with and without right children and to use upwards traversal only when necessary. This results in a clean, elegant, and optimal solution.