DEV Community

Ertugrul
Ertugrul

Posted on

๐Ÿ—“ Daily LeetCode Progress โ€“ Day 22

Problems Solved:

  • #230 Kth Smallest Element in a BST
  • #236 Lowest Common Ancestor of a Binary Tree

This continues my daily series (Day 22: Inorder Traversal + Divide & Conquer). Today I solved two core binary-tree patterns: using an inorder traversal on a BST to extract sorted order and find the kโ€‘th smallest, and a clean divideโ€‘andโ€‘conquer DFS to compute the LCA in a general binary tree.


๐Ÿ’ก What I Learned

  • Kth Smallest in BST (#230): Because an inorder traversal of a BST yields values in nonโ€‘decreasing order, we can increment a counter during traversal and return when the counter hits k. This creates a simple earlyโ€‘exit pattern.
  • LCA in Binary Tree (#236): A postโ€‘order style DFS works neatly: if a subtree returns nonโ€‘null for both p and q, the current node is the LCA. If only one side is nonโ€‘null, bubble that node upward.
  • General tips:

    • Donโ€™t compare node.val to p/q objectsโ€”compare nodes directly for LCA.
    • For BST inorder solutions, keep a mutable counter/state ( member variables in C++ or self fields in Python) and stop early whenfound.

๐Ÿงฉ #230 โ€” Kth Smallest Element in a BST

C++ (Recursive Inorder with early stop, O(n))

/**
  * Definition for a binary tree node.
  * struct TreeNode {
  *   int val;
  *   TreeNode *left;
  *   TreeNode *right;
  *   TreeNode() : val(0), left(nullptr), right(nullptr) {}
  *   TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
  *   TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
  * };
 */
class Solution {
public:
    int count = 0;
    int result = -1;

    void inorder(TreeNode* node, int k) {
        if (!node || result != -1) return;
        inorder(node->left, k);
        count++;
        if (count == k) {
            result = node->val;
            return;
        }
        inorder(node->right, k);
    }

    int kthSmallest(TreeNode* root, int k) {
        inorder(root, k);
        return result;
    }
};
Enter fullscreen mode Exit fullscreen mode

Python (Recursive Inorder, O(n))

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def kthSmallest(self, root, k):
        self.count = 0
        self.result = None

        def inorder(node):
            if not node:
                return
            inorder(node.left)
            self.count += 1
            if self.count == k:
                self.result = node.val
                return
            inorder(node.right)

        inorder(root)
        return self.result
Enter fullscreen mode Exit fullscreen mode

Key idea: Inorder on BST == sorted order. Maintain a counter and return once k is reached.

Complexity: O(h + k) average when the early stop prunes (worstโ€‘case O(n)), O(h) recursion stack where h is tree height.


๐Ÿงฉ #236 โ€” Lowest Common Ancestor of a Binary Tree

C++ (Divide & Conquer DFS, O(n))

/**
  * Definition for a binary tree node.
  * struct TreeNode {
  *   int val;
  *   TreeNode *left;
  *   TreeNode *right;
  *   TreeNode(int x) : val(x), left(NULL), right(NULL) {}
  * };
 */
class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if (!root || root == p || root == q) return root;

        TreeNode* left = lowestCommonAncestor(root->left, p, q);
        TreeNode* right = lowestCommonAncestor(root->right, p, q);

        if (left && right) return root;   // p and q in different subtrees
        return left ? left : right;       // both in the same subtree or not found here
    }
};
Enter fullscreen mode Exit fullscreen mode

Python (Divide & Conquer DFS, O(n))

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
        if not root or root == p or root == q:
            return root

        left = self.lowestCommonAncestor(root.left, p, q)
        right = self.lowestCommonAncestor(root.right, p, q)

        if left and right:
            return root
        return left if left else right
Enter fullscreen mode Exit fullscreen mode

Key idea: Postโ€‘order style recursion: return a nonโ€‘null pointer if p or q is found in a subtree; if both sides return nonโ€‘null, the current node is the LCA.

Complexity: O(n) time (each node visited once), O(h) recursion stack.


๐Ÿ“ธ Achievements

  • Implemented inorder traversal with early stopping to fetch the kโ€‘th smallest efficiently on BSTs.
  • Solved LCA on general binary trees with a concise divideโ€‘andโ€‘conquer DFS.

๐Ÿ“ฆ Complexity Recap

  • Kth Smallest (BST): O(h + k) average (worst O(n)), O(h) stack.

Kth py

Kth cpp

  • LCA (Binary Tree): O(n) time, O(h) stack.

LCA py

LCA cpp


๐Ÿ“ฃ Join the Journey

Iโ€™m solving and documenting problems daily in both Python and C++, covering trees, graphs, stacks/queues, and classic traversal patterns. Follow along if youโ€™re into clean patterns and crossโ€‘language implementations!

Links:

Top comments (0)