Minimum Time to Visit Disappearing Nodes solution and explanation
7 more videos on this problem
3112. Minimum Time to Visit Disappearing Nodes | Dijkstras | GraphAryan Mittal · 9:03 · 2K views
Leetcode Biweekly contest 128 || 100279. Minimum Time to Visit Disappearing Nodes || Python3Ezy Codes · 0:43 · 1K views
Biweekly Contest 128 | Minimum Time to Visit Disappearing NodesCodeWithMe21 · 7:38 · 454 views
C. Minimum Time to Visit Disappearing Nodes| Leetcode solution JAVA | Leetcode Biweekly Contest 128JUST CODE · 0:56 · 407 views
3112. Minimum Time to Visit Disappearing Nodes (Leetcode Medium)Programming Live with Larry · 12:59 · 375 views
3112. Minimum Time to Visit Disappearing Nodes | LEETCODE BIWEEKLY 128 | dijkstra's algorithmcode Explainer · 12:33 · 238 views
LeetCode | 3112. Minimum Time to Visit Disappearing Nodes | Medium | Biweekly Contest 128Coding with Bobby · 9:21 · 202 views
[力扣每日一題] LC 3112. Minimum Time to Visit Disappearing Nodes 访问消失节点的最少时间 - Medium- Java - DijkstraLeetcode刷題最後希望 · 12:10 · 98 views
The problem
There is an undirected graph of n nodes. You are given a 2D array edges, where edges[i] = [ui, vi, lengthi] describes an edge between node ui and node vi with a traversal time of lengthi units.
Additionally, you are given an array disappear, where disappear[i] denotes the time when the node i disappears from the graph and you won't be able to visit it.
Note that the graph might be disconnected and might contain multiple edges.
Return the array answer, with answer[i] denoting the minimum units of time required to reach node i from node 0. If node i is unreachable from node 0 then answer[i] is -1.
Example 1:
Input: n = 3, edges = [[0,1,2],[1,2,1],[0,2,4]], disappear = [1,1,5]
Output: [0,-1,4]
Explanation:

We are starting our journey from node 0, and our goal is to find the minimum time required to reach each node before it disappears.
- For node 0, we don't need any time as it is our starting point.
- For node 1, we need at least 2 units of time to traverse
edges[0]. Unfortunately, it disappears at that moment, so we won't be able to visit it. - For node 2, we need at least 4 units of time to traverse
edges[2].
Example 2:
Input: n = 3, edges = [[0,1,2],[1,2,1],[0,2,4]], disappear = [1,3,5]
Output: [0,2,3]
Explanation:

We are starting our journey from node 0, and our goal is to find the minimum time required to reach each node before it disappears.
- For node 0, we don't need any time as it is the starting point.
- For node 1, we need at least 2 units of time to traverse
edges[0]. - For node 2, we need at least 3 units of time to traverse
edges[0]andedges[1].
Example 3:
Input: n = 2, edges = [[0,1,1]], disappear = [1,1]
Output: [0,-1]
Explanation:
Exactly when we reach node 1, it disappears.
Constraints:
1 <= n <= 5 * 1040 <= edges.length <= 105edges[i] == [ui, vi, lengthi]0 <= ui, vi <= n - 11 <= lengthi <= 105disappear.length == n1 <= disappear[i] <= 105
Approach overview
Problem Overview: You are given a weighted graph and an array disappear where each node becomes inaccessible after a specific time. Starting from node 0, compute the minimum time to reach every node before it disappears. If a node cannot be reached in time, its answer is -1.
Approach 1: Dijkstra's Algorithm with Disappearance Constraint (O((n+m) log n) time, O(n+m) space)
This problem behaves like a classic shortest path search with one extra rule: you cannot enter a node if the arrival time is greater than or equal to its disappearance time. Use Dijkstra’s algorithm with a heap (priority queue) to always process the node with the smallest current travel time. For each edge relaxation, compute next_time = current_time + weight and only push the neighbor if next_time < disappear[neighbor]. Maintain a distance array to avoid revisiting nodes with worse times. This approach works well because edge weights vary, and the priority queue guarantees the earliest feasible arrival is processed first.
Approach 2: Breadth-First Search with Edge Constraints (O(n+m) time, O(n+m) space)
If edge traversal behaves close to uniform or you structure the traversal level-by-level, a constrained BFS-style traversal can work. Store states in a queue and track the earliest time each node can be reached. When exploring neighbors, calculate the arrival time and skip the transition if the node would already have disappeared. This method still relies on pruning invalid states early and maintaining a visited or distance array to avoid redundant processing. Conceptually it treats the graph as layers of reachable states while enforcing the disappearance rule during expansion. It is useful for simpler implementations when edge weights or constraints allow near-linear traversal.
Recommended for interviews: Dijkstra’s algorithm is the expected solution. Interviewers want to see that you recognize the problem as a constrained graph shortest-path variant and modify the relaxation condition using the disappearance time. A brute traversal shows understanding of graph exploration, but the priority queue solution demonstrates mastery of shortest-path optimization.
Approach 1: Dijkstra's Algorithm with Constraints
Dijkstra's Algorithm with Constraints:
Use Dijkstra's algorithm to find the shortest paths from node 0 to all other nodes. However, during the traversal, consider the disappearance times of the nodes. If a node is reached after its disappearance time, consider it unreachable for that path.
import heapq
def minimum_time(n, edges, disappear):
graph = {i: [] for i in range(n)}
for u, v, length in edges:
graph[u].append((v, length))
graph[v].append((u, length))
min_heap = [(0, 0)] # (time, node)
min_time = [float('inf')] * n
min_time[0] = 0
while min_heap:
current_time, u = heapq.heappop(min_heap)
if current_time > min_time[u] or current_time >= disappear[u]:
continue
for v, length in graph[u]:
time = current_time + length
if time < min_time[v] and time < disappear[v]:
min_time[v] = time
heapq.heappush(min_heap, (time, v))
return [t if t != float('inf') else -1 for t in min_time]import java.util.*;
public class Solution {
static class Edge {
int node, time;
Edge(int n, int t) { node = n; time = t; }
}
public int[] minimumTime(int n, int[][] edges, int[] disappear) {
List<List<Edge>> graph = new ArrayList<>();
for (int i = 0; i < n; i++)
graph.add(new ArrayList<>());
for (int[] edge : edges) {
graph.get(edge[0]).add(new Edge(edge[1], edge[2]));
graph.get(edge[1]).add(new Edge(edge[0], edge[2]));
}
PriorityQueue<Edge> minHeap = new PriorityQueue<>(Comparator.comparingInt(e -> e.time));
minHeap.offer(new Edge(0, 0));
int[] minTime = new int[n];
Arrays.fill(minTime, Integer.MAX_VALUE);
minTime[0] = 0;
while (!minHeap.isEmpty()) {
Edge cur = minHeap.poll();
if (cur.time > minTime[cur.node] || cur.time >= disappear[cur.node])
continue;
for (Edge neighbor : graph.get(cur.node)) {
int newTime = cur.time + neighbor.time;
if (newTime < minTime[neighbor.node] && newTime < disappear[neighbor.node]) {
minTime[neighbor.node] = newTime;
minHeap.offer(new Edge(neighbor.node, newTime));
}
}
}
for (int i = 0; i < n; i++)
if (minTime[i] == Integer.MAX_VALUE) minTime[i] = -1;
return minTime;
}
}This solution utilizes a modified version of Dijkstra's algorithm. The algorithm maintains a priority queue to ensure processing nodes with the least cumulative time first. Every time a node is dequeued, it checks if it was reached before its disappearance time. If not, it's effectively unreachable. This ensures all nodes that can be visited in time are correctly calculated.
Time Complexity: O((n + e) log n), where n is the number of nodes and e is the number of edges.
Space Complexity: O(n + e), to store the graph and auxiliary data.
Approach 2: Breadth-First Search with Edge Constraints
Breadth-First Search with Edge Constraints:
Employ a breadth-first search (BFS) to explore the graph from the starting node. Use a queue to manage nodes to explore and ensure to update the shortest time to reach each node. Similar to Dijkstra, ensure that any node visited must be checked against its disappearance time to ensure the path is valid.
#include <vector>
#include <queue>
#include <limits.h>
using namespace std;
struct Edge {
int node, time;
Edge(int n, int t) : node(n), time(t) {}
};
vector<int> minimumTime(int n, vector<vector<int>>& edges, vector<int>& disappear) {
vector<vector<Edge>> graph(n);
for (auto& edge : edges) {
graph[edge[0]].push_back(Edge(edge[1], edge[2]));
graph[edge[1]].push_back(Edge(edge[0], edge[2]));
}
queue<Edge> q;
q.push(Edge(0, 0));
vector<int> minTime(n, INT_MAX);
minTime[0] = 0;
while (!q.empty()) {
Edge cur = q.front(); q.pop();
if (cur.time >= disappear[cur.node]) continue;
for (Edge& neighbor : graph[cur.node]) {
int time = cur.time + neighbor.time;
if (time < minTime[neighbor.node] && time < disappear[neighbor.node]) {
minTime[neighbor.node] = time;
q.push(Edge(neighbor.node, time));
}
}
}
for (int& time : minTime) if (time == INT_MAX) time = -1;
return minTime;
}using System;
using System.Collections.Generic;
public class Solution {
private class Edge {
public int Node, Time;
public Edge(int n, int t) { Node = n; Time = t; }
}
public int[] MinimumTime(int n, int[][] edges, int[] disappear) {
var graph = new List<List<Edge>>();
for (int i = 0; i < n; i++) graph.Add(new List<Edge>());
foreach (var edge in edges) {
graph[edge[0]].Add(new Edge(edge[1], edge[2]));
graph[edge[1]].Add(new Edge(edge[0], edge[2]));
}
var minTime = new int[n];
Array.Fill(minTime, int.MaxValue);
minTime[0] = 0;
var queue = new Queue<Edge>();
queue.Enqueue(new Edge(0, 0));
while (queue.Count > 0) {
Edge cur = queue.Dequeue();
if (cur.Time >= disappear[cur.Node]) continue;
foreach (Edge neighbor in graph[cur.Node]) {
int time = cur.Time + neighbor.Time;
if (time < minTime[neighbor.Node] && time < disappear[neighbor.Node]) {
minTime[neighbor.Node] = time;
queue.Enqueue(new Edge(neighbor.Node, time));
}
}
}
for (int i = 0; i < n; i++)
if (minTime[i] == int.MaxValue) minTime[i] = -1;
return minTime;
}
}This C++ solution uses a BFS approach to explore the graph. A simple queue is used instead of a priority queue, but we must still ensure that paths followed are viable by checking the disappear quality of nodes. Similar to BFS, this approach traverses layer by layer in time when optimizing reachability.
Time Complexity: O(n + e), because each node and edge is processed once.
Space Complexity: O(n + e), to store nodes and other state data.
Approach 3: Heap-Optimized Dijkstra
First, we create an adjacency list g to store the edges of the graph. Then, we create an array dist to store the shortest distances from node 0 to other nodes. Initialize dist[0] = 0, and the distances for the rest of the nodes are initialized to infinity.
Next, we use the Dijkstra algorithm to calculate the shortest distances from node 0 to other nodes. The specific steps are as follows:
- Create a priority queue
pqto store the distances and node numbers. Initially, add node0to the queue with a distance of0. - Remove a node
ufrom the queue. If the distanceduofuis greater thandist[u], it meansuhas already been updated, so we skip it directly. - Iterate through all neighbor nodes
vof nodeu. Ifdist[v] > dist[u] + wanddist[u] + w < disappear[v], then updatedist[v] = dist[u] + wand add nodevto the queue. - Repeat steps 2 and 3 until the queue is empty.
Finally, we iterate through the dist array. If dist[i] < disappear[i], then answer[i] = dist[i]; otherwise, answer[i] = -1.
The time complexity is O(m times log m), and the space complexity is O(m). Here, m is the number of edges.
function minimumTime(n: number, edges: number[][], disappear: number[]): number[] {
const g: [number, number][][] = Array.from({ length: n }, () => []);
for (const [u, v, w] of edges) {
g[u].push([v, w]);
g[v].push([u, w]);
}
const dist = Array.from({ length: n }, () => Infinity);
dist[0] = 0;
const pq = new PriorityQueue({
compare: (a, b) => (a[0] === b[0] ? a[1] - b[1] : a[0] - b[0]),
});
pq.enqueue([0, 0]);
while (pq.size() > 0) {
const [du, u] = pq.dequeue()!;
if (du > dist[u]) {
continue;
}
for (const [v, w] of g[u]) {
if (dist[v] > dist[u] + w && dist[u] + w < disappear[v]) {
dist[v] = dist[u] + w;
pq.enqueue([dist[v], v]);
}
}
}
return dist.map((a, i) => (a < disappear[i] ? a : -1));
}func minimumTime(n int, edges [][]int, disappear []int) []int {
g := make([][]pair, n)
for _, e := range edges {
u, v, w := e[0], e[1], e[2]
g[u] = append(g[u], pair{v, w})
g[v] = append(g[v], pair{u, w})
}
dist := make([]int, n)
for i := range dist {
dist[i] = 1 << 30
}
dist[0] = 0
pq := hp{{0, 0}}
for len(pq) > 0 {
du, u := pq[0].dis, pq[0].u
heap.Pop(&pq)
if du > dist[u] {
continue
}
for _, nxt := range g[u] {
v, w := nxt.dis, nxt.u
if dist[v] > dist[u]+w && dist[u]+w < disappear[v] {
dist[v] = dist[u] + w
heap.Push(&pq, pair{dist[v], v})
}
}
}
ans := make([]int, n)
for i := 0; i < n; i++ {
if dist[i] < disappear[i] {
ans[i] = dist[i]
} else {
ans[i] = -1
}
}
return ans
}
type pair struct{ dis, u int }
type hp []pair
func (h hp) Len() int { return len(h) }
func (h hp) Less(i, j int) bool { return h[i].dis < h[j].dis }
func (h hp) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
func (h *hp) Push(v any) { *h = append(*h, v.(pair)) }
func (h *hp) Pop() any { a := *h; v := a[len(a)-1]; *h = a[:len(a)-1]; return v }Complexity comparison
| Approach | Complexity |
|---|---|
| Dijkstra's Algorithm with Constraints | Time Complexity: O((n + e) log n), where n is the number of nodes and e is the number of edges. |
| Breadth-First Search with Edge Constraints | Time Complexity: O(n + e), because each node and edge is processed once. |
| Heap-Optimized Dijkstra | – |
Complexity analysis
| Approach | Time | Space | When to Use |
|---|---|---|---|
| Dijkstra's Algorithm with Disappearance Constraint | O((n+m) log n) | O(n+m) | General weighted graph case where edges have different travel times |
| Breadth-First Search with Edge Constraints | O(n+m) | O(n+m) | When traversal behaves close to uniform or constraints allow simple queue-based exploration |
Frequently asked questions
Is Minimum Time to Visit Disappearing Nodes easy or hard?
The problem is rated Medium because it extends a classic shortest-path algorithm with an additional constraint. Understanding Dijkstra's algorithm is required, but the main twist is verifying that each node is reached before its disappearance time.
Minimum Time to Visit Disappearing Nodes Python or Java solution
Python and Java implementations typically use Dijkstra's algorithm with adjacency lists and a priority queue (heapq in Python or PriorityQueue in Java). During edge relaxation, the algorithm checks that the arrival time is less than the node's disappearance time before updating the distance.
How to solve Minimum Time to Visit Disappearing Nodes in O(n log n)?
Model the graph with adjacency lists and run Dijkstra from node 0. For each neighbor, compute the arrival time and only continue if the time is smaller than disappear[neighbor]. Using a min-heap keeps the next node with the smallest travel time at the top, producing the earliest valid arrival for every node.
What is the best approach for Minimum Time to Visit Disappearing Nodes?
Dijkstra's algorithm with a constraint on node disappearance is the most reliable approach. Each time you relax an edge, you verify that the arrival time is strictly less than the node's disappear time. The priority queue ensures the earliest reachable nodes are processed first, giving an overall complexity of O((n+m) log n).
Is Minimum Time to Visit Disappearing Nodes asked at Google/Amazon/Meta?
Graph shortest-path variants with constraints appear frequently in interviews at companies like Google, Amazon, and Meta. Problems that modify Dijkstra with additional rules—such as time windows, disappearing nodes, or restricted edges—are common interview patterns.
What data structure is used in Minimum Time to Visit Disappearing Nodes?
The key data structure is a min-heap (priority queue) used by Dijkstra's algorithm to always process the node with the smallest known arrival time. The graph itself is stored as an adjacency list, and an array tracks the shortest valid arrival time for each node.
What is the time complexity of Minimum Time to Visit Disappearing Nodes?
The optimal solution using Dijkstra's algorithm runs in O((n+m) log n) time where n is the number of nodes and m is the number of edges. Each edge relaxation may trigger a heap operation. Space complexity is O(n+m) for the adjacency list, distance array, and priority queue.
