Talentd
FleetCode
Make and follow sheets.Sign in

Second Minimum Node In a Binary Tree solution and explanation

EasyBinary TreeDepth-First SearchTree6 min read46.0% acceptanceUpdated 9 Apr 2026
Second Minimum Node In a Binary Tree | Leetcode 671nETSETOS · 11:46 · 4K viewsWatch on YouTube
9 more videos on this problem
  1. Second Minimum Node In a Binary Tree | Leetcode 671nETSETOS · 11:46 · 4K views
  2. Second Minimum Node In a Binary Tree | LEETCODE - 671 | Easy solutionhi-malik · 5:36 · 2K views
  3. 671. Second Minimum Node In a Binary Tree (Leetcode Easy)Programming Live with Larry · 7:11 · 911 views
  4. Second Minimum Node In a Binary Tree | Leetcode 671 | Amazon Google Facebook interview questionSuper Lazy Coder · 7:05 · 809 views
  5. LeetCode 671. Second Minimum Node In a Binary Tree Solution Explained - JavaAlgorithms and Data Structures Course · 7:33 · 787 views
  6. Second Minimum Node In a Binary Tree LeetCode:671Tensordroid · 5:21 · 694 views
  7. 671. Second Minimum Node In a Binary Tree | Leetcode | PythonAbdullah Arshed · 2:27 · 212 views
  8. LeetCode - Second Minimum Node In a Binary Treeciaociao_o · 9:25 · 202 views
  9. LeetCode 671 | Second Minimum Node In a Binary Tree | JavaSleepy Cracker · 3:06 · 183 views
  10. Leetcode solving: 671. Second Minimum Node In a Binary TreeMath Geeks · 2:23 · 109 views

The problem

Given a non-empty special binary tree consisting of nodes with the non-negative value, where each node in this tree has exactly two or zero sub-node. If the node has two sub-nodes, then this node's value is the smaller value among its two sub-nodes. More formally, the property root.val = min(root.left.val, root.right.val) always holds.

Given such a binary tree, you need to output the second minimum value in the set made of all the nodes' value in the whole tree.

If no such second minimum value exists, output -1 instead.

Example 1:

Input: root = [2,2,5,null,null,5,7]
Output: 5
Explanation: The smallest value is 2, the second smallest value is 5.

Example 2:

Input: root = [2,2,2]
Output: -1
Explanation: The smallest value is 2, but there isn't any second smallest value.

Constraints:

  • The number of nodes in the tree is in the range [1, 25].
  • 1 <= Node.val <= 231 - 1
  • root.val == min(root.left.val, root.right.val) for each internal node of the tree.

Approach overview

Problem Overview: You are given a special binary tree where every non-leaf node has exactly two children and its value equals the smaller of its two children's values. Because of this rule, the root always contains the smallest value in the entire tree. The task is to find the second smallest value across all nodes. If such a value does not exist, return -1.

Approach 1: Recursive Depth-First Search (DFS) (Time: O(n), Space: O(h))

This approach traverses the tree using recursion and tracks the smallest value (which is always the root). During traversal, you look for the smallest value strictly greater than root.val. DFS works well because you can explore each subtree while maintaining the current candidate for the second minimum. When visiting a node, if its value is greater than the root value, it becomes a candidate and you compare it with the best answer found so far. Otherwise, you continue exploring its children. Since every node may need to be visited in the worst case, the time complexity is O(n). The recursion stack uses O(h) space where h is the tree height.

The key insight comes from the tree property: each parent equals the minimum of its children. That means any value greater than root.val automatically qualifies as a candidate for the second minimum. DFS naturally explores deeper branches first and is a clean way to implement this logic in problems involving Depth-First Search on a Binary Tree.

Approach 2: Iterative Breadth-First Search (BFS) (Time: O(n), Space: O(n))

The BFS approach uses a queue to traverse the tree level by level. Start by storing the root's value as the global minimum. While processing nodes from the queue, check if the node value is greater than the root value. If it is, update the second minimum candidate. If the node value equals the root value, its children might still contain larger values, so push them into the queue for further exploration. This ensures that all potential candidates are examined.

BFS processes nodes iteratively and avoids recursion. The time complexity remains O(n) because each node is processed once. The queue can store up to a full level of the tree, resulting in O(n) auxiliary space in the worst case. BFS is commonly used when working with general Tree traversals and is helpful when recursion depth could become large.

Recommended for interviews: The recursive DFS solution is usually preferred. It directly leverages the special property of the tree and keeps the code compact. Interviewers typically expect you to recognize that the root already holds the minimum value and then search for the smallest value greater than it using a full traversal. BFS is equally valid but slightly more verbose.

Approach 1: Recursive Depth-First Search (DFS) Approach

This approach utilizes the recursive Depth-First Search (DFS) to traverse through the binary tree. Since each parent node value is equal to the minimum of its two children nodes, we need to traverse the tree to collect candidate values for the second minimum. This is done by keeping track of unique values found during traversal.

class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None

class Solution:
    def findSecondMinimumValue(self, root: TreeNode) -> int:
        self.first = root.val
        self.second = -1

        def dfs(node):
            if node:
                if self.first < node.val < self.second or self.second == -1:
                    self.second = node.val
                dfs(node.left)
                dfs(node.right)

        dfs(root)
        return self.second
class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode(int x) { val = x; }
}

public class Solution {
    private int first;
    private int second = -1;

    public int findSecondMinimumValue(TreeNode root) {
        first = root.val;
        dfs(root);
        return second;
    }

    private void dfs(TreeNode node) {
        if (node != null) {
            if (first < node.val && (second == -1 || node.val < second)) {
                second = node.val;
            }
            dfs(node.left);
            dfs(node.right);
        }
    }
}
#include <iostream>
#include <limits.h>
using namespace std;

struct TreeNode {
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};

void dfs(TreeNode* root, int &min, int &second_min) {
    if (!root) return;
    if (root->val != min) {
        if (second_min == -1 || root->val < second_min) {
            second_min = root->val;
        }
    }
    dfs(root->left, min, second_min);
    dfs(root->right, min, second_min);
}

int findSecondMinimumValue(TreeNode* root) {
    if (!root) return -1;
    int min = root->val;
    int second_min = -1;
    dfs(root, min, second_min);
    return second_min;
}
function TreeNode(val) {
    this.val = val;
    this.left = this.right = null;
}

var findSecondMinimumValue = function(root) {
    let first = root.val;
    let second = -1;

    function dfs(node) {
        if (node) {
            if (first < node.val && (second === -1 || node.val < second)) {
                second = node.val;
            }
            dfs(node.left);
            dfs(node.right);
        }
    }
    dfs(root);
    return second;
};
#include <stdio.h>
#include <limits.h>

struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
};

void dfs(struct TreeNode* root, int *min, int *second_min) {
    if (!root) return;
    if (root->val != *min) {
        if (*second_min == -1 || root->val < *second_min) {
            *second_min = root->val;
        }
    }
    dfs(root->left, min, second_min);
    dfs(root->right, min, second_min);
}

int findSecondMinimumValue(struct TreeNode* root) {
    if (!root) return -1;
    int min = root->val;
    int second_min = -1;
    dfs(root, &min, &second_min);
    return second_min;
}
public class TreeNode {
    public int val;
    public TreeNode left;
    public TreeNode right;
    public TreeNode(int x) { val = x; }
}

public class Solution {
    private int first;
    private int second = -1;

    public int FindSecondMinimumValue(TreeNode root) {
        first = root.val;
        DFS(root);
        return second;
    }

    private void DFS(TreeNode node) {
        if (node != null) {
            if (first < node.val && (second == -1 || node.val < second)) {
                second = node.val;
            }
            DFS(node.left);
            DFS(node.right);
        }
    }
}

In the Python implementation, a recursive DFS is used, where the first and second minimums are initialized, and a helper function is used to explore the tree. It updates the second minimum when it encounters a node value that's a valid candidate.

Complexity

Time Complexity: O(n), where n is the number of nodes.
Space Complexity: O(h), recursion stack height (h).

Try this approach in the editor

Approach 2: Iterative Breadth-First Search (BFS) Approach

This approach utilizes an iterative Breadth-First Search (BFS) using a queue to process nodes level by level. It maintains a minimum and a candidate for the second minimum. By using a level-order traversal, it systematically updates the second minimum whenever a node with a greater value than the minimum is discovered.

import collections

class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None

class Solution:
    def findSecondMinimumValue(self, root: TreeNode) -> int:
        if not root:
            return -1
        first = root.val
        second = -1
        queue = collections.deque([root])
        while queue:
            node = queue.popleft()
            if first < node.val < second or second == -1:
                second = node.val
            if node.left:
                queue.append(node.left)
            if node.right:
                queue.append(node.right)
        return second
import java.util.LinkedList;
import java.util.Queue;

class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode(int x) { val = x; }
}

public class Solution {
    public int findSecondMinimumValue(TreeNode root) {
        if (root == null) return -1;
        int first = root.val;
        int second = -1;
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        while (!queue.isEmpty()) {
            TreeNode node = queue.poll();
            if (node.val > first && (second == -1 || node.val < second)) {
                second = node.val;
            }
            if (node.left != null) queue.offer(node.left);
            if (node.right != null) queue.offer(node.right);
        }
        return second;
    }
}
#include <iostream>
#include <limits.h>
#include <queue>
using namespace std;

struct TreeNode {
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};

int findSecondMinimumValue(TreeNode* root) {
    if (!root) return -1;
    int first = root->val, second = -1;
    queue<TreeNode*> q;
    q.push(root);
    while (!q.empty()) {
        TreeNode *node = q.front(); q.pop();
        if (node->val > first && (second == -1 || node->val < second)) {
            second = node->val;
        }
        if (node->left) q.push(node->left);
        if (node->right) q.push(node->right);
    }
    return second;
}
function TreeNode(val) {
    this.val = val;
    this.left = this.right = null;
}

var findSecondMinimumValue = function(root) {
    if (!root) return -1;
    let first = root.val;
    let second = -1;
    let queue = [root];
    while (queue.length > 0) {
        let node = queue.shift();
        if (node.val > first && (second === -1 || node.val < second)) {
            second = node.val;
        }
        if (node.left) queue.push(node.left);
        if (node.right) queue.push(node.right);
    }
    return second;
};
#include <stdio.h>
#include <limits.h>
#include <stdlib.h>

typedef struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
} TreeNode;

int findSecondMinimumValue(TreeNode* root) {
    if (!root) return -1;
    int first = root->val, second = -1;
    TreeNode **queue = (TreeNode **)malloc(100 * sizeof(TreeNode*));
    int front = 0, rear = 0;
    queue[rear++] = root;
    while (front < rear) {
        TreeNode *node = queue[front++];
        if (node->val > first && (second == -1 || node->val < second)) {
            second = node->val;
        }
        if (node->left) queue[rear++] = node->left;
        if (node->right) queue[rear++] = node->right;
    }
    free(queue);
    return second;
}
using System.Collections.Generic;

public class TreeNode {
    public int val;
    public TreeNode left;
    public TreeNode right;
    public TreeNode(int x) { val = x; }
}

public class Solution {
    public int FindSecondMinimumValue(TreeNode root) {
        if (root == null) return -1;
        int first = root.val;
        int second = -1;
        Queue<TreeNode> queue = new Queue<TreeNode>();
        queue.Enqueue(root);
        while (queue.Count > 0) {
            TreeNode node = queue.Dequeue();
            if (node.val > first && (second == -1 || node.val < second)) {
                second = node.val;
            }
            if (node.left != null) queue.Enqueue(node.left);
            if (node.right != null) queue.Enqueue(node.right);
        }
        return second;
    }
}

In the Python code, a BFS approach is employed using a deque. The process involves enqueuing nodes as they are discovered, with conditions checking to ascertain and possibly update the second minimum candidate based on node values.

Complexity

Time Complexity: O(n).
Space Complexity: O(w) where w is the maximum number of nodes in a level within the queue.

Try this approach in the editor

Approach 3: Default Approach

/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
func findSecondMinimumValue(root *TreeNode) int {
	ans, v := -1, root.Val
	var dfs func(*TreeNode)
	dfs = func(root *TreeNode) {
		if root == nil {
			return
		}
		dfs(root.Left)
		dfs(root.Right)
		if root.Val > v {
			if ans == -1 || ans > root.Val {
				ans = root.Val
			}
		}
	}
	dfs(root)
	return ans
}
Try this approach in the editor

Complexity comparison

ApproachComplexity
Recursive Depth-First Search (DFS) Approach

Time Complexity: O(n), where n is the number of nodes.
Space Complexity: O(h), recursion stack height (h).

Iterative Breadth-First Search (BFS) Approach

Time Complexity: O(n).
Space Complexity: O(w) where w is the maximum number of nodes in a level within the queue.

Default Approach–

Complexity analysis

ApproachTimeSpaceWhen to Use
Recursive Depth-First Search (DFS)O(n)O(h)Preferred interview solution; clean recursion that leverages tree properties
Iterative Breadth-First Search (BFS)O(n)O(n)Useful when avoiding recursion or when performing level-order traversal

Frequently asked questions

Is Second Minimum Node In a Binary Tree easy or hard?

LeetCode classifies this problem as Easy. The main challenge is recognizing the special property of the tree where each parent equals the smaller child. Once you understand that the root already holds the minimum value, the task becomes a straightforward tree traversal to find the next larger value.

Second Minimum Node In a Binary Tree Python/Java solution

Python and Java implementations typically perform a DFS starting from the root and track the smallest value greater than root.val. The same logic works across languages like C++, C#, and JavaScript. Each node is visited once, giving O(n) time complexity with minimal additional memory.

How to solve Second Minimum Node In a Binary Tree in O(n)?

Start by storing the root value as the smallest element. Traverse the tree using DFS or BFS and check each node's value. If a node value is greater than the root value, update the current second minimum candidate. Continue exploring nodes with the same value as the root since their children might contain larger values. This single traversal guarantees O(n) time.

What is the best approach for Second Minimum Node In a Binary Tree?

Recursive Depth-First Search (DFS) is the most common approach. Traverse the tree while tracking the smallest value greater than the root value. Because the root is guaranteed to contain the minimum element, any larger value encountered during traversal becomes a candidate for the second minimum. This approach runs in O(n) time with O(h) recursion space.

Is Second Minimum Node In a Binary Tree asked at Google/Amazon/Meta?

Tree traversal problems like this frequently appear in interviews at companies such as Amazon, Google, and Meta. Variants often test understanding of DFS, BFS, and properties of binary trees. The problem is commonly used to evaluate traversal logic and candidate filtering during tree searches.

What data structure is used in Second Minimum Node In a Binary Tree?

The problem primarily uses a binary tree structure along with traversal techniques. DFS implementations rely on recursion (implicit stack), while BFS solutions use a queue to process nodes level by level. No additional complex data structures are required.

What is the time complexity of Second Minimum Node In a Binary Tree?

The optimal solution runs in O(n) time because every node may need to be visited once to verify whether it could be the second minimum. DFS or BFS traversal both achieve this complexity. Space complexity is O(h) for recursive DFS due to the call stack, or O(n) for BFS because of the queue.

Comments

Now write it yourselfClose this page and solve Second Minimum Node In a Binary Tree in the editor, without looking.
Practise Second Minimum Node In a Binary Tree