V

Algorithm Visualizer

ZHEN
Share on WeiboShare on XGitHub repositoryAuthor website
Learning ToolsAlgorithm Complexity ReferenceAlgorithm Learning Paths
Data StructuresArrayLinked ListStackQueue and DequeBinary Search TreeBinary HeapHash TableGraphTrieDisjoint Set UnionLRU CacheSkip ListSegment TreeB+ TreeBloom FilterFenwick Tree
SortingBubble SortCocktail Shaker SortBitonic SortSelection SortInsertion SortBinary Insertion SortShell SortMerge SortTop-Down Merge SortQuick SortThree-Way Quick SortDual-Pivot Quick SortHeap SortCounting SortRadix SortBucket Sort
Graph AlgorithmsDijkstra's Shortest PathKruskal's Minimum Spanning TreePrim's Minimum Spanning TreeBellman-Ford Shortest PathsTopological SortFloyd-WarshallStrongly Connected Components2-SATMaximum FlowBipartite MatchingLowest Common AncestorEulerian Path
Dynamic ProgrammingEdit Distance0/1 KnapsackUnbounded KnapsackLongest Common SubsequenceLongest Increasing SubsequenceCoin ChangeStone MergingTraveling Salesperson DPTree Dynamic ProgrammingDigit DPRerooting DP
Backtracking and SearchN-QueensSubsetsPermutationsCombination SumMaze Solving with DFSNumber of IslandsWord SearchSudoku SolverA* Search
StringsKMP String MatchingRabin-Karp String MatchingBoyer-Moore String MatchingManacher's Longest Palindromic SubstringSuffix ArrayLCP ArrayAho-Corasick AutomatonZ Function
Math and Number TheorySieve of EratosthenesLinear SieveEuclidean AlgorithmBinary ExponentiationExtended Euclidean AlgorithmChinese Remainder TheoremEuler's Totient FunctionMiller-Rabin Primality TestFast Fourier TransformPollard's Rho Factorization
Computational GeometryConvex HullRotating CalipersClosest Pair of PointsLine Segment IntersectionBentley-Ottmann Sweep Line
SearchingBinary SearchLower and Upper BoundSearch in a Rotated Sorted ArrayBinary Search on the AnswerTernary Search

Maze Solving with DFS

Grid search with visited cells and path backtracking

Explore one route as deeply as possible

Depth-first search enters an open neighboring cell, marks it visited, and continues from there. Walls, boundaries, and visited cells are rejected. The visited set prevents cycles, while a separate path stack records the cells on the current candidate route.

Dead ends trigger an undo

If a cell has no unvisited open neighbor, remove it from the active path and return to the previous cell. That previous recursive call can then try another direction. Reaching the goal stops the search with the current path intact.

The player uses a fixed 5 by 5 maze. Amber cells form the current DFS path, previously visited cells remain visible, dark cells are walls, and the successful start-to-goal route turns green.

🐭
🚩

Start at (0, 0) and search for goal (4, 4).

1function solveMaze(grid: number[][], sr: number, sc: number, gr: number, gc: number) {
2 const visited = new Set<string>();
3 const path: [number, number][] = [];
4 const dfs = (r: number, c: number): boolean => {
5 const key = r + ',' + c;
6 if (r < 0 || r >= grid.length || c < 0 || c >= grid[0].length) return false;
7 if (grid[r][c] === 1 || visited.has(key)) return false; // wall / visited
8 visited.add(key);
9 path.push([r, c]); // move to (r,c)
10 if (r === gr && c === gc) return true; // reach the goal
11 for (const [dr, dc] of [[1,0],[0,1],[-1,0],[0,-1]]) { // four directions
12 if (dfs(r + dr, c + dc)) return true;
13 }
14 path.pop(); // dead end: backtrack one cell
15 return false;
16 };
17 dfs(sr, sc);
18 return path;
19}
Start(0,0)
Goal(4,4)
Current cell(0,0)
Path length1
Visited1
1 / 19

One path, not necessarily the shortest

With a visited set, DFS processes each grid cell at most once, taking O(RC) time and space. It finds a path when one exists, but not necessarily the shortest path. Breadth-first search is the standard unweighted-grid choice when minimum step count matters.

Invariant: the active path is always a simple route from the start to the current cell, and every removed cell remains visited so the search cannot loop.

Compare grid backtracking with board constraints in N-Queens and explicit choices in Subsets.