What is the dynamic programming algorithm for finding a Hamiltonian cycle in a graph?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
The standard dynamic programming method for Hamiltonian cycle is the Held-Karp style subset DP. It does not make the problem easy in the general case, but it reduces brute force from factorial time to roughly O(n^2 2^n), which is much better for small graphs.
Core Idea of the DP
Pick a start vertex, usually 0, and build paths that begin there and visit subsets of vertices exactly once. The state records two things:
- which vertices have already been visited
- which vertex the current path ends at
A common boolean state is:
dp[mask][v] = True if there is a path starting at 0, visiting exactly the vertices in mask, and ending at v.
The bitmask stores the subset. If bit i is on, vertex i is included in the partial path.
Transition Rule
From a valid state dp[mask][u], you can extend to a neighbor v when:
- '
vis not already inmask' - there is an edge from
utov
That produces:
dp[mask | (1 << v)][v] = True
Once all vertices have been visited, you only need one final check: can the end vertex connect back to the start vertex 0? If yes, a Hamiltonian cycle exists.
Python Example
This implementation assumes an adjacency matrix where graph[u][v] is True when an edge exists:
Output:
Why It Works
The DP avoids recomputing the same partial path question again and again. Instead of asking "is there some path over these vertices ending here?" many times recursively, it stores the answer once and reuses it.
That is the essence of the dynamic programming improvement over plain backtracking.
Recovering the Actual Cycle
If you need the cycle itself instead of a yes-or-no answer, store a parent pointer for each successful state. Then, once you find an end vertex that connects back to the start, walk the parents backward to reconstruct the full order of vertices.
This raises memory usage a bit, but the asymptotic time stays the same.
Complexity
There are 2^n possible subsets and up to n possible endpoints for each subset. For each state, transitions may inspect up to n next vertices.
That gives:
- time complexity:
O(n^2 2^n) - space complexity:
O(n 2^n)
This is still exponential, so it is practical only for relatively small graphs. But compared with checking all permutations, it is a major improvement.
Common Pitfalls
- Forgetting that Hamiltonian cycle is still NP-complete even with dynamic programming.
- Mixing up Hamiltonian cycle and Hamiltonian path. The cycle must return to the start.
- Using a DP table without a fixed start vertex, which creates redundant symmetric states.
- Expecting this method to scale to very large graphs.
- Forgetting the final edge check from the last vertex back to the start.
Summary
- The classic DP algorithm is the Held-Karp subset dynamic programming method.
- States are defined by a visited-set bitmask and an ending vertex.
- Transitions extend valid partial paths to unvisited neighbors.
- After visiting all vertices, you must still verify that the path closes into a cycle.
- The algorithm runs in
O(n^2 2^n)time and is practical for small graphs, not large ones.

