2Brute2Best
πŸ”₯0

Search in a Binary Search Tree

EasyΒ·LeetCode #700Basic Anchor
LeetCode
30-Second Mental ModelTree DFS β€” BST properties (walk one path, go left or right)
Complexity:O(N)β†’O(H)
Key Insight

Start at the root. If val is smaller than the current value, the answer can only be on the left, so the right side is thrown away. If it is bigger, go right. Stop when the value matches or the walk runs off the tree.

Core Validity Invariant

The answer, if it exists, is always inside the subtree rooted at cur.

01

Problem

You are given the root of a binary search tree and a number val.

Find the node whose value is val, and return that node. The node keeps its children, so its whole subtree comes back with it. If no node holds val, return null.

Input

The root of a binary search tree (between 1 and 5000 nodes) and an integer val.

Output

The node whose value is val (the subtree rooted at it), or null if no node has that value.

Example 1
Input: root = [4, 2, 7, 1, 3], val = 2
Output: the node 2, with children 1 and 3 (LeetCode shows [2, 1, 3])

Node 2 holds the value we want, so we return it. Its subtree is 2 with children 1 and 3.

Example 2
Input: root = [4, 2, 7, 1, 3], val = 5
Output: null

No node holds 5. The walk goes 4 β†’ 7, then 7 has no left child, so it runs off the tree.

Constraints
  • β€’ The number of nodes is between 1 and 5000
  • β€’ 1 ≀ Node.val ≀ 10^7
  • β€’ root is a binary search tree
  • β€’ 1 ≀ val ≀ 10^7
02

First, think yourself

Before opening any solution, try to answer these on paper. Use hints only when stuck β€” each hint is counted.

  1. 1.

    The tree is a binary search tree. If I stand at one node and compare val with its value, what does that tell me about the two sides?

  2. 2.

    Could val sit in the right subtree of a node whose value is bigger than val? Why or why not?

  3. 3.

    Which two things can end my search, and what does each one mean for the answer?

  4. 4.

    Do I need recursion or a stack here, or is a single pointer enough?

  5. 5.

    On a chain of 5000 nodes that leans to the right, how many nodes can the search visit? What changes for a balanced tree?

03

Brute force approach

05

Optimized approach

06

Why does this algorithm work?

07

Dry run

08

All approaches compared

ApproachIdeaTimeSpace
Brute ForceIgnore the BST order: check a node, then search its left and right subtreesO(N)O(H)
OptimalCompare `val` with the current node, then step to the one child that can hold itO(H)O(1)
09

Why does this belong to this pattern?

Clues in the problem statement
  • β€œbinary search tree”Left < node < right. One comparison tells you which side can hold the target.
  • β€œreturn the node with value val”Return the node itself, not a copy. Its subtree comes with it.
  • β€œnot found β†’ null”The walk must stop cleanly when it falls off the tree.
BST order: left < node < right+one comparison per level+return the node or null→Tree DFS — BST properties (walk one path, go left or right)

This is binary search on a tree. Each comparison throws away one whole side, the same way binary search throws away half of a sorted array. The tree version needs no stack or recursion, because each step keeps only one candidate: the current node. The search does not need the other side because the BST order already rules it out.

10

Don't make this mistake

Searching both sides like a plain tree (pattern confusion)
βœ— TreeNode* found = searchBST(root->left, val); if (found) return found; return searchBST(root->right, val);
βœ“ if (!root || root->val == val) return root; return searchBST(val < root->val ? root->left : root->right, val);

The two-sided search still returns the right node, so a small test passes. But it throws away the BST order. On [5,3,8,2,4,7,9,1] with val = 6, the two-sided search visits all 8 nodes. The BST walk goes 5 β†’ 8 β†’ 7 and stops after 3.

Comparing with the wrong side
βœ— cur = val > cur->val ? cur->left : cur->right;
βœ“ cur = val < cur->val ? cur->left : cur->right;

The two sides are swapped, so the walk goes the wrong way. On [5,3,8,2,4,7,9,1] with val = 4: 4 < 5, but the code goes right to 8, then left to 7, then null. It returns null even though 4 is in the tree.

Returning a new node instead of the one in the tree
βœ— return new TreeNode(cur->val);
βœ“ return cur;

The value is right, but a new node has no children, so the subtree is lost. The answer is the existing node. On [4,2,7,1,3] with val = 2, the copy would lose the children 1 and 3.

Dereferencing null when the value is missing
βœ— while (cur->val != val) { cur = val < cur->val ? cur->left : cur->right; }
βœ“ while (cur && cur->val != val) { cur = val < cur->val ? cur->left : cur->right; }

When val is not in the tree, cur becomes null and cur->val crashes. On [4,2,7,1,3] with val = 5, the walk goes 4 β†’ 7 β†’ null, and the check on null is the crash.

11

Want to implement this?

Write it yourself on LeetCode, then come back and compare your code with the solutions above.

Open coding workspace
How did it go?
Beyond The LeetCode Problem

How this concept connects to System Design & C++ Systems

Bridge DSA with production engineering

Top engineering interviews test whether you understand how algorithms like Tree DFS translate into production architectures and low-level memory mechanics.