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
key
during a search down the tree.Successor: The last node encountered with value greater than
key
during a search down the tree.
Algorithm Steps:
Initialize two pointers:
pre
andsuc
tonullptr
.To find predecessor:
Start from root.
Move right if current node's value
< key
, updatepre
to current node.Else move left.
To find successor:
Start from root.
Move left if current node's value
> key
, updatesuc
to 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
h
is 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