1. DFS with 2D Visited Matrix
Intuition
From (r, c), check boundaries, obstacle value, and !visited[r][c]. Recurse into valid neighbors in D, L, R, U order.
When to apply: Explicit 4-branch recursion with auxiliary 2D visited array.
Algorithm
- Step 1: Check if start (0,0) or destination (n-1, n-1) is 0; if so, return empty list.
- Step 2: Maintain a 2D boolean array visited of size N x N.
- Step 3: At cell (r, c), mark visited[r][c] = true.
- Step 4: Explicitly try moving Down (
D), Left (L), Right (R), Up (U) if neighbor is within bounds, open (1), and unvisited. - Step 5: When reaching (n-1, n-1), append path string to result.
- Step 6: Backtrack by resetting visited[r][c] = false.
#include <iostream>#include <vector>#include <string> class Solution {public: void backtrack(int r, int c, int n, std::vector<std::vector<int>>& mat, std::vector<std::vector<bool>>& visited, std::string& path, std::vector<std::string>& result) { if (r == n - 1 && c == n - 1) { result.push_back(path); return; } visited[r][c] = true; // Down if (r + 1 < n && mat[r + 1][c] == 1 && !visited[r + 1][c]) { path.push_back('D'); backtrack(r + 1, c, n, mat, visited, path, result); path.pop_back(); } // Left if (c - 1 >= 0 && mat[r][c - 1] == 1 && !visited[r][c - 1]) { path.push_back('L'); backtrack(r, c - 1, n, mat, visited, path, result); path.pop_back(); } // Right if (c + 1 < n && mat[r][c + 1] == 1 && !visited[r][c + 1]) { path.push_back('R'); backtrack(r, c + 1, n, mat, visited, path, result); path.pop_back(); } // Up if (r - 1 >= 0 && mat[r - 1][c] == 1 && !visited[r - 1][c]) { path.push_back('U'); backtrack(r - 1, c, n, mat, visited, path, result); path.pop_back(); } visited[r][c] = false; } std::vector<std::string> findPath(std::vector<std::vector<int>>& mat) { int n = mat.size(); std::vector<std::string> result; if (mat[0][0] == 0 || mat[n - 1][n - 1] == 0) return result; std::vector<std::vector<bool>> visited(n, std::vector<bool>(n, false)); std::string path = ""; backtrack(0, 0, n, mat, visited, path, result); return result; }}; int main() { Solution solver; std::vector<std::vector<int>> mat = { {1, 0, 0, 0}, {1, 1, 0, 1}, {1, 1, 0, 0}, {0, 1, 1, 1} }; std::vector<std::string> paths = solver.findPath(mat); std::cout << "Paths:\n"; for (const auto& p : paths) std::cout << p << "\n"; return 0;}Time & Space Complexity
- Time complexity:
O(4^(N^2))— Each cell can branch in up to 4 directions. - Space complexity:
O(N^2)— O(N2) for the visited boolean array and recursion call stack.