27. Print Leaf Nodes from Preorder Traversal of BST
The problem can be found at the following link: 🔗 Question Link
🧩 Problem Description
Given the preorder traversal of a Binary Search Tree (BST), print all the leaf nodes of this BST without actually reconstructing the tree.
❗Note:
It is guaranteed that the input preorder is of a valid BST.
The output order must follow the order of the leaf nodes as they appear during preorder traversal.
📘 Examples
Example 1:
Input:
preorder = [5, 2, 10]Output:
[2, 10]Explanation: The BST is:
5 / \ 2 10
Leaf nodes are 2 and 10.
Example 2:
Input:
preorder = [4, 2, 1, 3, 6, 5]Output:
[1, 3, 5]Explanation: The BST is:
Leaf nodes are 1, 3, 5.
Example 3:
Input:
preorder = [8, 2, 5, 10, 12]Output:
[5, 12]Explanation: The BST is:
Leaf nodes are 5 and 12.
🔒 Constraints
$
1 ≤ preorder.size() ≤ 10^3$$
1 ≤ preorder[i] ≤ 10^3$
✅ My Approach
Single-Pass Stack Sweep
We can determine leaf nodes directly by observing when a node’s value is “popped over” by a larger successor in preorder. Maintain a stack of ancestors; whenever the next value exceeds stack-top, the previous node is a leaf.
Algorithm Steps:
Initialize an empty stack
stand an empty result listleafs.Iterate index
ifrom0topreorder.size() - 2:Let
cur = preorder[i],nxt = preorder[i+1].If
cur > nxt, pushcurontost.Else (i.e.,
nxt > cur):While
!st.empty()andnxt > st.top(), popstand mark a flag.If flag was set (we popped at least once), record
curas a leaf.
After loop, always append the last element
preorder.back()as a leaf.Return
leafs.
🧮 Time and Auxiliary Space Complexity
Expected Time Complexity: O(n), as we scan the array once and each element is pushed and popped at most once.
Expected Auxiliary Space Complexity: O(n), as in the worst case (strictly decreasing preorder) all elements go into the stack.
🧠 Code (C++)
⚡ Alternative Approaches
📊 2️⃣ Recursive BST Reconstruction + DFS
Algorithm Steps:
Reconstruct BST from
preorderusing a helperbuild(preorder, idx, bound):If
idx == norpreorder[idx] > bound, returnnullptr.Create node
uwithpreorder[idx++].u->left = build(preorder, idx, u->val);u->right = build(preorder, idx, bound);
DFS on this tree:
If
uhas no children, recordu->valinleafs.Recurse on
u->leftthenu->right.
✅ Why This Approach?
🏗️ Builds the exact BST structure for clarity.
🔍 Separates tree construction from leaf-collection.
📝 Complexity Analysis:
Time: 🟢 O(n) — each element inserted once, each visited once in DFS.
Auxiliary Space: 🔸 O(n) — recursion stack + newly allocated nodes.
📊 3️⃣ Divide & Conquer on Array
Algorithm Steps:
Define
void solve(l, r)over subarraypreorder[l…r].If
l == r, recordpreorder[l]as leaf and return.Find
m= first index in(l+1…r]such thatpreorder[m] > preorder[l].Recurse on
[l+1, m-1](left subtree) and[m, r](right subtree).
✅ Why This Approach?
📏 Works purely on the array, no extra DS beyond call stack.
🎯 Directly identifies leaves by subarray bounds.
📝 Complexity Analysis:
Time: 🔸 O(n²) worst-case (e.g., sorted preorder).
Auxiliary Space: 🔸 O(n) recursion depth.
🆚 Comparison of Approaches
Approach
⏱️ Time
🗂️ Space
✅ Pros
⚠️ Cons
▶️ Stack Sweep
🟢 O(n)
🟢 O(n)
Single pass, no tree nodes allocated
Uses auxiliary stack
🔁 Recursive BST + DFS
🟢 O(n)
🟢 O(n)
Clean separation, true BST structure
Allocates nodes, recursion cost
🪜 Divide & Conquer on Array
🔸 O(n²) worst
🟢 O(n)
No extra DS, direct on array
Quadratic on pathological input
✅ Best Choice by Scenario
Scenario
Recommended
🏆 Fastest and simplest
🥇 Stack Sweep
📚 Need explicit BST structure
🥈 Recursive BST + DFS
💡 Working purely on array without nodes
🥉 Divide & Conquer
🧑💻 Code (Java)
🐍 Code (Python)
🧠 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