graph TD
A(15):::greenShade
A --- B(10):::orangeShade
A --- C(20)
B --- D(8)
B --- E(12):::blueShade
C --- F(16)
C --- G(25)
classDef greenShade fill:#32CD32,stroke:#000,stroke-width:1px,color:#fff;
classDef orangeShade fill:#FFA500,stroke:#000,stroke-width:1px,color:#000;
classDef blueShade fill:#1E90FF,stroke:#000,stroke-width:1px,color:#fff;
1
2
3
4
5
6
Input:
BST =[15,10,20,8,12,16,25], target =12Output:
Predecessor =10, Successor =15Explanation:
Predecessor is the largest node less than 12, which is10. Successor is the smallest node greater than 12, which is15.
graph TD
A(15):::blueShade
A --- B(10):::orangeShade
A --- C(20):::greenShade
B --- D(8)
B --- E(12)
C --- F(16)
C --- G(25)
classDef greenShade fill:#32CD32,stroke:#000,stroke-width:1px,color:#fff;
classDef orangeShade fill:#FFA500,stroke:#000,stroke-width:1px,color:#000;
classDef blueShade fill:#1E90FF,stroke:#000,stroke-width:1px,color:#fff;
1
2
3
4
5
6
Input:
BST =[15,10,20,8,12,16,25], target =15Output:
Predecessor =12, Successor =16Explanation:
Predecessor is the largest node less than 15, which is12. Successor is the smallest node greater than 15, which is16.
A predecessor in BST lies in the left subtree, and its value is the maximum of the left child if it exists.
Similarly, a successor in BST lies in the right subtree. Its value is the minimum of the right child if it exists.
If a given node does not have left or right children, we recursively search for its predecessor and successor by examining the parent-subtree relationship.
classSolution:
deffindPredecessorAndSuccessor(self, root, target):
stack = []
current = root
predecessor, successor =None, None last_visited =Nonewhile stack or current:
# Push left nodes to stackwhile current:
stack.append(current)
current = current.left
# Visit the node current = stack.pop()
# Track predecessor (last visited node before target)if last_visited and last_visited.val == target:
successor = current # First node visited after targetbreakif current.val < target:
predecessor = current # Candidate for predecessor last_visited = current
# Move to the right subtree current = current.right
return predecessor.val if predecessor elseNone, successor.val if successor elseNone