19. Predecessor and Successor
The problem can be found at the following link: 🔗 Question Link
🧩 Problem Description
Given the root of a Binary Search Tree (BST) and an integer key, find the inorder predecessor and successor of the key in the BST.
The predecessor is the largest value in the BST smaller than the key.
The successor is the smallest value in the BST larger than the key.
If predecessor or successor does not exist, return
NULL.
Example 1:
Input: root = [8, 1, 9, N, 4, N, 10, 3, N, N, N], key = 8
Output: 4 9
Explanation: The inorder predecessor of 8 is 4, and the inorder successor is 9.
Example 2:
Input: root = [10, 2, 11, 1, 5, N, N, N, N, 3, 6, N, 4, N, N], key = 11
Output: 10 -1
Explanation: The inorder predecessor of 11 is 10, and successor does not exist.
Example 3:
Input: root = [2, 1, 3], key = 3
Output: 2 -1
Explanation: The inorder predecessor of 3 is 2, and successor does not exist.
🔒 Constraints
$1 \leq \text{Number of Nodes} \leq 10^4$
$1 <= node->data <= 10^6$
$1 \leq \text{Key Value} \leq 10^5$
✅ My Approach
Iterative BST Search Using BST Properties
The BST property allows us to find predecessor and successor without full traversal:
Predecessor: The last node encountered with value less than
keyduring a search down the tree.Successor: The last node encountered with value greater than
keyduring a search down the tree.
Algorithm Steps:
Initialize two pointers:
preandsuctonullptr.To find predecessor:
Start from root.
Move right if current node's value
< key, updatepreto current node.Else move left.
To find successor:
Start from root.
Move left if current node's value
> key, updatesucto current node.Else move right.
Return the pair
{pre, suc}.
This approach leverages BST ordering and runs in time proportional to the height of the tree, typically O(log N) for balanced BSTs.
🧮 Time and Auxiliary Space Complexity
Expected Time Complexity: O(h), where
his the height of the BST, as each search for predecessor and successor traverses at most from root to leaf.Expected Auxiliary Space Complexity: O(1), as we use only a fixed number of pointers and no extra data structures.
🧠 Code (C++)
class Solution {
public:
vector<Node*> findPreSuc(Node* root, int key) {
Node *pre = nullptr, *suc = nullptr;
Node* curr = root;
while (curr) {
if (curr->data < key) {
pre = curr;
curr = curr->right;
} else curr = curr->left;
}
curr = root;
while (curr) {
if (curr->data > key) {
suc = curr;
curr = curr->left;
} else curr = curr->right;
}
return {pre, suc};
}
};🧑💻 Code (Java)
class Solution {
public ArrayList<Node> findPreSuc(Node root, int key) {
Node pre = null, suc = null, curr = root;
while (curr != null) {
if (curr.data < key) {
pre = curr;
curr = curr.right;
} else {
curr = curr.left;
}
}
curr = root;
while (curr != null) {
if (curr.data > key) {
suc = curr;
curr = curr.left;
} else {
curr = curr.right;
}
}
ArrayList<Node> res = new ArrayList<>();
res.add(pre);
res.add(suc);
return res;
}
}🐍 Code (Python)
class Solution:
def findPreSuc(self, root, key):
pre = suc = None
curr = root
while curr:
if curr.data < key:
pre = curr
curr = curr.right
else:
curr = curr.left
curr = root
while curr:
if curr.data > key:
suc = curr
curr = curr.left
else:
curr = curr.right
return [pre, suc]🧠 Contribution and Support
For discussions, questions, or doubts related to this solution, feel free to connect on LinkedIn: 📬 Any Questions?. Let’s make this learning journey more collaborative!
⭐ If you find this helpful, please give this repository a star! ⭐
📍Visitor Count
Last updated