Off-by-one on range boundaries
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.
Move from brute-force thinking to an efficient approach using array strategy.
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.
edges[0]. Unfortunately, it disappears at that moment, so we won't be able to visit it.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.
edges[0].edges[0] and edges[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] <= 105Problem summary: 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.
Start with the most direct exhaustive search. That gives a correctness anchor before optimizing.
Pattern signal: Array
3 [[0,1,2],[1,2,1],[0,2,4]] [1,1,5]
3 [[0,1,2],[1,2,1],[0,2,4]] [1,3,5]
2 [[0,1,1]] [1,1]
find-the-last-marked-nodes-in-tree)Source-backed implementations are provided below for direct study and interview prep.
// Accepted solution for LeetCode #3112: Minimum Time to Visit Disappearing Nodes
class Solution {
public int[] minimumTime(int n, int[][] edges, int[] disappear) {
List<int[]>[] g = new List[n];
Arrays.setAll(g, k -> new ArrayList<>());
for (var e : edges) {
int u = e[0], v = e[1], w = e[2];
g[u].add(new int[] {v, w});
g[v].add(new int[] {u, w});
}
int[] dist = new int[n];
Arrays.fill(dist, 1 << 30);
dist[0] = 0;
PriorityQueue<int[]> pq = new PriorityQueue<>((a, b) -> a[0] - b[0]);
pq.offer(new int[] {0, 0});
while (!pq.isEmpty()) {
var e = pq.poll();
int du = e[0], u = e[1];
if (du > dist[u]) {
continue;
}
for (var nxt : g[u]) {
int v = nxt[0], w = nxt[1];
if (dist[v] > dist[u] + w && dist[u] + w < disappear[v]) {
dist[v] = dist[u] + w;
pq.offer(new int[] {dist[v], v});
}
}
}
int[] ans = new int[n];
for (int i = 0; i < n; ++i) {
ans[i] = dist[i] < disappear[i] ? dist[i] : -1;
}
return ans;
}
}
// Accepted solution for LeetCode #3112: Minimum Time to Visit Disappearing Nodes
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 }
# Accepted solution for LeetCode #3112: Minimum Time to Visit Disappearing Nodes
class Solution:
def minimumTime(
self, n: int, edges: List[List[int]], disappear: List[int]
) -> List[int]:
g = defaultdict(list)
for u, v, w in edges:
g[u].append((v, w))
g[v].append((u, w))
dist = [inf] * n
dist[0] = 0
pq = [(0, 0)]
while pq:
du, u = heappop(pq)
if du > dist[u]:
continue
for v, w in g[u]:
if dist[v] > dist[u] + w and dist[u] + w < disappear[v]:
dist[v] = dist[u] + w
heappush(pq, (dist[v], v))
return [a if a < b else -1 for a, b in zip(dist, disappear)]
// Accepted solution for LeetCode #3112: Minimum Time to Visit Disappearing Nodes
// Rust example auto-generated from java reference.
// Replace the signature and local types with the exact LeetCode harness for this problem.
impl Solution {
pub fn rust_example() {
// Port the logic from the reference block below.
}
}
// Reference (java):
// // Accepted solution for LeetCode #3112: Minimum Time to Visit Disappearing Nodes
// class Solution {
// public int[] minimumTime(int n, int[][] edges, int[] disappear) {
// List<int[]>[] g = new List[n];
// Arrays.setAll(g, k -> new ArrayList<>());
// for (var e : edges) {
// int u = e[0], v = e[1], w = e[2];
// g[u].add(new int[] {v, w});
// g[v].add(new int[] {u, w});
// }
// int[] dist = new int[n];
// Arrays.fill(dist, 1 << 30);
// dist[0] = 0;
// PriorityQueue<int[]> pq = new PriorityQueue<>((a, b) -> a[0] - b[0]);
// pq.offer(new int[] {0, 0});
// while (!pq.isEmpty()) {
// var e = pq.poll();
// int du = e[0], u = e[1];
// if (du > dist[u]) {
// continue;
// }
// for (var nxt : g[u]) {
// int v = nxt[0], w = nxt[1];
// if (dist[v] > dist[u] + w && dist[u] + w < disappear[v]) {
// dist[v] = dist[u] + w;
// pq.offer(new int[] {dist[v], v});
// }
// }
// }
// int[] ans = new int[n];
// for (int i = 0; i < n; ++i) {
// ans[i] = dist[i] < disappear[i] ? dist[i] : -1;
// }
// return ans;
// }
// }
// Accepted solution for LeetCode #3112: Minimum Time to Visit Disappearing Nodes
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));
}
Use this to step through a reusable interview workflow for this problem.
Two nested loops check every pair or subarray. The outer loop fixes a starting point, the inner loop extends or searches. For n elements this gives up to n²/2 operations. No extra space, but the quadratic time is prohibitive for large inputs.
Most array problems have an O(n²) brute force (nested loops) and an O(n) optimal (single pass with clever state tracking). The key is identifying what information to maintain as you scan: a running max, a prefix sum, a hash map of seen values, or two pointers.
Review these before coding to avoid predictable interview regressions.
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.