Tarjan articulation points
Time O(V + E) Space O(V + E)DFS with disc/low; mark u when the rule holds; collect marked nodes in order.
n = 5, edges = [[0,1],[1,2],[2,0],[1,3],[3,4]]disc / low(map)
Step 1/4DFS 0 → 1 → 2. 2 has a back edge to 0, so low[2] = 0. That is below disc[1] = 1, so this child doesn't make 1 a weak spot.
import java.util.*;
class Solution {
private List<List<Integer>> adj;
private int[] disc, low;
private boolean[] cut;
private int time = 0;
public List<Integer> articulationPoints(int n, int[][] edges) {
adj = new ArrayList<>();
for (int i = 0; i < n; i++) adj.add(new ArrayList<>());
for (int[] e : edges) { adj.get(e[0]).add(e[1]); adj.get(e[1]).add(e[0]); }
disc = new int[n];
low = new int[n];
cut = new boolean[n];
Arrays.fill(disc, -1);
dfs(0, -1);
List<Integer> out = new ArrayList<>();
for (int i = 0; i < n; i++) if (cut[i]) out.add(i);
return out;
}
private void dfs(int u, int parent) {
disc[u] = low[u] = time++;
int children = 0;
for (int v : adj.get(u)) {
if (v == parent) continue;
if (disc[v] == -1) {
children++;
dfs(v, u);
low[u] = Math.min(low[u], low[v]);
if (parent != -1 && low[v] >= disc[u]) cut[u] = true;
} else {
low[u] = Math.min(low[u], disc[v]);
}
}
if (parent == -1 && children > 1) cut[u] = true;
}
}Verdict: Same DFS as bridges, different test.