Articulation Points in Graph in DSA Javascript - Time & Space Complexity
We want to understand how the time needed to find articulation points changes as the graph grows.
How does the algorithm's work increase when the graph has more nodes and edges?
Analyze the time complexity of the following code snippet.
function dfs(u, parent) {
visited[u] = true;
disc[u] = low[u] = time++;
let children = 0;
for (const v of graph[u]) {
if (!visited[v]) {
children++;
dfs(v, u);
low[u] = Math.min(low[u], low[v]);
if (parent === -1 && children > 1) articulation[u] = true;
if (parent !== -1 && low[v] >= disc[u]) articulation[u] = true;
} else if (v !== parent) {
low[u] = Math.min(low[u], disc[v]);
}
}
}
This code finds articulation points using a depth-first search on the graph.
Look for loops and recursive calls that repeat work.
- Primary operation: The depth-first search visits each node and checks all its neighbors.
- How many times: Each node and edge is visited once during the search.
As the graph grows, the algorithm visits every node and edge once.
| Input Size (n nodes, m edges) | Approx. Operations |
|---|---|
| 10 nodes, 15 edges | About 25 visits (nodes + edges) |
| 100 nodes, 200 edges | About 300 visits |
| 1000 nodes, 5000 edges | About 6000 visits |
Pattern observation: The work grows roughly in proportion to the number of nodes plus edges.
Time Complexity: O(n + m)
This means the time grows linearly with the total number of nodes and edges in the graph.
[X] Wrong: "The algorithm checks every pair of nodes, so it must be O(n²)."
[OK] Correct: The algorithm only visits each edge once, not every pair of nodes, so it is faster than O(n²).
Understanding this time complexity helps you explain how graph algorithms scale and why efficient traversal matters.
"What if the graph was represented as an adjacency matrix instead of adjacency lists? How would the time complexity change?"
Practice
Solution
Step 1: Understand the definition of articulation point
An articulation point is a vertex that, if removed, increases the number of disconnected parts in the graph.Step 2: Compare options with definition
Only A vertex that, when removed, increases the number of connected components matches this definition exactly.Final Answer:
A vertex that, when removed, increases the number of connected components -> Option AQuick Check:
Articulation point = vertex increasing components when removed [OK]
- Confusing articulation point with highest degree vertex
- Thinking articulation point is always connected to all vertices
- Assuming isolated vertices are articulation points
Solution
Step 1: Understand adjacency list initialization
We need an array of separate empty arrays for each vertex to store neighbors.Step 2: Analyze options
const graph = new Array(n).fill([]); uses fill([]), which fills all positions with the same array reference (wrong). const graph = Array.from({ length: n }, () => []); uses Array.from with a function returning new arrays, so each vertex has its own array (correct). const graph = Array(n).fill(null); fills with null, not arrays. const graph = new Map(); uses Map, which is valid but not the typical adjacency list array.Final Answer:
const graph = Array.from({ length: n }, () => []); -> Option AQuick Check:
Separate arrays per vertex = const graph = Array.from({ length: n }, () => []); [OK]
- Using fill([]) creates shared references causing bugs
- Initializing with null instead of arrays
- Confusing Map with adjacency list array
const graph = [[1,2],[0],[0,3],[2]];
const visited = [false, false, false, false];
const disc = [0, 0, 0, 0];
const low = [0, 0, 0, 0];
const parent = [-1, -1, -1, -1];
const ap = [false, false, false, false];
let time = 0;
function dfs(u) {
visited[u] = true;
disc[u] = low[u] = ++time;
let children = 0;
for (const v of graph[u]) {
if (!visited[v]) {
children++;
parent[v] = u;
dfs(v);
low[u] = Math.min(low[u], low[v]);
if (parent[u] === -1 && children > 1) ap[u] = true;
if (parent[u] !== -1 && low[v] >= disc[u]) ap[u] = true;
} else if (v !== parent[u]) {
low[u] = Math.min(low[u], disc[v]);
}
}
}
dfs(0);
console.log(ap);What will be the output printed?
Solution
Step 1: Trace DFS and articulation point logic
Start DFS at 0: children are 1 and 2. For root (0), if children > 1, ap[0] = true. So 0 is articulation point. For vertex 2, low[3] >= disc[2] triggers ap[2] = true.Step 2: Determine articulation points array
Vertices 0 and 2 are articulation points, others are not. So ap = [true, false, true, false].Final Answer:
[true, false, true, false] -> Option BQuick Check:
Root with >1 child and low[v]>=disc[u] mark articulation points [OK]
- Ignoring root special case with multiple children
- Confusing low and disc arrays
- Not updating low[u] on back edges
function dfs(u) {
visited[u] = true;
disc[u] = low[u] = ++time;
let children = 0;
for (const v of graph[u]) {
if (!visited[v]) {
children++;
parent[v] = u;
dfs(v);
low[u] = Math.min(low[u], low[v]);
if (low[v] >= disc[u]) ap[u] = true;
} else if (v !== parent[u]) {
low[u] = Math.min(low[u], disc[v]);
}
}
}What is the bug in this code?
Solution
Step 1: Analyze articulation point conditions
The code checks if low[v] >= disc[u] to mark articulation points but misses the special case for root vertex which requires children > 1.Step 2: Identify missing root condition
Without checking if u is root and has multiple children, root articulation points won't be detected.Final Answer:
It misses the root vertex articulation point condition -> Option DQuick Check:
Root articulation point requires separate children > 1 check [OK]
- Forgetting root vertex special case
- Using wrong comparison operator in articulation check
- Not updating parent array before DFS call
Solution
Step 1: Visualize the graph and connections
Vertices 0,1,2 form a triangle. Vertex 1 connects to 3, which connects to 4.Step 2: Identify articulation points
Removing 1 disconnects 3 and 4 from the rest, so 1 is articulation point. Removing 3 disconnects 4, so 3 is articulation point. 0,2,4 are not articulation points.Final Answer:
[1, 3] -> Option CQuick Check:
Vertices connecting subgraphs are articulation points [OK]
- Including vertices inside cycles as articulation points
- Missing leaf node articulation points
- Confusing articulation points with bridges
Ready to prove it?
Pass the test and this pattern moves unknown
