|
| 1 | +<h1 align='center'>Rat - In a - Maze</h1> |
| 2 | + |
| 3 | +## Problem Statement |
| 4 | + |
| 5 | +**Problem URL :** [Rat in a Maze](https://www.geeksforgeeks.org/problems/rat-in-a-maze-problem/1) |
| 6 | + |
| 7 | + |
| 8 | + |
| 9 | + |
| 10 | +## Problem Explanation |
| 11 | +#### **Problem Statement:** |
| 12 | +The problem is called **"Rat in a Maze"** and is about finding all possible paths for a rat to travel from the top-left corner `(0, 0)` of a square matrix to the bottom-right corner `(n-1, n-1)`. The matrix is a grid where: |
| 13 | +- `1` represents a cell the rat can move to. |
| 14 | +- `0` represents a cell that is blocked. |
| 15 | + |
| 16 | +The rat can move in four directions: |
| 17 | +1. **Down ('D')** |
| 18 | +2. **Left ('L')** |
| 19 | +3. **Right ('R')** |
| 20 | +4. **Up ('U')** |
| 21 | + |
| 22 | +The goal is to return all the paths that the rat can take to reach the destination. If no path exists, return an empty list. |
| 23 | + |
| 24 | + |
| 25 | + |
| 26 | +#### **Example:** |
| 27 | +**Input:** |
| 28 | +```plaintext |
| 29 | +n = 4 |
| 30 | +maze = [ |
| 31 | + [1, 0, 0, 0], |
| 32 | + [1, 1, 0, 1], |
| 33 | + [1, 1, 0, 0], |
| 34 | + [0, 1, 1, 1] |
| 35 | +] |
| 36 | +``` |
| 37 | + |
| 38 | +**Output:** |
| 39 | +```plaintext |
| 40 | +["DDRDRR", "DRDDRR"] |
| 41 | +``` |
| 42 | + |
| 43 | +**Explanation:** |
| 44 | +- The rat starts at `(0, 0)` and needs to reach `(3, 3)`. The valid paths are: |
| 45 | + - `DDRDRR`: Down → Down → Right → Down → Right → Right |
| 46 | + - `DRDDRR`: Down → Right → Down → Down → Right → Right |
| 47 | + |
| 48 | + |
| 49 | + |
| 50 | +#### **Approach:** |
| 51 | +To solve this problem, we use **backtracking**, which allows us to explore all possible paths and backtrack when a path is invalid. Here's the step-by-step approach: |
| 52 | + |
| 53 | +1. **Check if a Move is Valid:** |
| 54 | + Use the `isSafe` function to check: |
| 55 | + - The new position `(newX, newY)` is within bounds. |
| 56 | + - The cell `(newX, newY)` is not already visited. |
| 57 | + - The cell `(newX, newY)` is `1` (open for movement). |
| 58 | + |
| 59 | +2. **Recursive Exploration:** |
| 60 | + - Start from `(0, 0)` and mark the cell as visited. |
| 61 | + - Try moving in all four possible directions (`D`, `L`, `R`, `U`) one by one. |
| 62 | + - Append the corresponding character to the current path string. |
| 63 | + |
| 64 | +3. **Base Case:** |
| 65 | + - If the rat reaches the destination `(n-1, n-1)`, store the path in the result. |
| 66 | + |
| 67 | +4. **Backtracking:** |
| 68 | + - After exploring all possible directions from a cell, reset the visited status of the cell (backtrack) to explore other paths. |
| 69 | + |
| 70 | +5. **Return Results:** |
| 71 | + - If there are no paths, return an empty list. Otherwise, return all valid paths. |
| 72 | + |
| 73 | + |
| 74 | +## Problem Solution |
| 75 | +```cpp |
| 76 | + |
| 77 | +``` |
| 78 | + |
| 79 | + |
| 80 | +## Problem Solution Explanation |
| 81 | + |
| 82 | +```cpp |
| 83 | +class Solution { |
| 84 | + public: |
| 85 | + // Function to check if moving to (newX, newY) is valid |
| 86 | + bool isSafe(int newX, int newY, vector<vector<bool>>& vis, vector<vector<int>>& arr, int n){ |
| 87 | + if((newX >= 0 && newX < n) && (newY >= 0 && newY < n) && vis[newX][newY] != 1 && arr[newX][newY] == 1) return true; |
| 88 | + return false; |
| 89 | + } |
| 90 | +``` |
| 91 | +- **`isSafe`:** This function ensures the rat doesn't go out of bounds, visit an already visited cell, or step into a blocked cell (`0`). |
| 92 | +
|
| 93 | +
|
| 94 | +
|
| 95 | +```cpp |
| 96 | + void solve(int x, int y, vector<vector<int>>& arr, int n, vector<string>& ans, vector<vector<bool>>& vis, string path){ |
| 97 | + if(x == n-1 && y == n-1){ // Base case: reached destination |
| 98 | + ans.push_back(path); // Add the path to the result |
| 99 | + return; |
| 100 | + } |
| 101 | + vis[x][y] = 1; // Mark the current cell as visited |
| 102 | +``` |
| 103 | +- **Base Case:** When `(x, y)` is the destination `(n-1, n-1)`, save the current path in `ans`. |
| 104 | +- **Mark as Visited:** The cell `(x, y)` is marked to avoid revisiting during this recursion path. |
| 105 | + |
| 106 | + |
| 107 | + |
| 108 | +```cpp |
| 109 | + if(isSafe(x+1, y, vis, arr, n)){ // Move Down |
| 110 | + solve(x+1, y, arr, n, ans, vis, path + 'D'); |
| 111 | + } |
| 112 | + |
| 113 | + if(isSafe(x, y-1, vis, arr, n)){ // Move Left |
| 114 | + solve(x, y-1, arr, n, ans, vis, path + 'L'); |
| 115 | + } |
| 116 | + |
| 117 | + if(isSafe(x, y+1, vis, arr, n)){ // Move Right |
| 118 | + solve(x, y+1, arr, n, ans, vis, path + 'R'); |
| 119 | + } |
| 120 | + |
| 121 | + if(isSafe(x-1, y, vis, arr, n)){ // Move Up |
| 122 | + solve(x-1, y, arr, n, ans, vis, path + 'U'); |
| 123 | + } |
| 124 | +``` |
| 125 | +- **Directional Moves:** Check all four directions (`D`, `L`, `R`, `U`) using `isSafe`. For each valid move, append the corresponding direction to the `path` string and recursively call `solve`. |
| 126 | +
|
| 127 | +
|
| 128 | +
|
| 129 | +```cpp |
| 130 | + vis[x][y] = 0; // Backtrack by unmarking the current cell |
| 131 | + } |
| 132 | +``` |
| 133 | +- **Backtracking:** Reset the cell `(x, y)` to unvisited so other paths can use it. |
| 134 | + |
| 135 | + |
| 136 | + |
| 137 | +```cpp |
| 138 | + vector<string> findPath(vector<vector<int>> &mat) { |
| 139 | + vector<string> ans; |
| 140 | + vector<vector<bool>> visited(mat.size(), vector<bool>(mat.size(), 0)); // Visited matrix |
| 141 | + string path = ""; |
| 142 | + solve(0, 0, mat, mat.size(), ans, visited, path); // Start solving from (0, 0) |
| 143 | + return ans; // Return all possible paths |
| 144 | + } |
| 145 | +}; |
| 146 | +``` |
| 147 | +- **`findPath`:** Initializes the visited matrix and starts the recursive `solve` function from `(0, 0)`. |
| 148 | +
|
| 149 | +
|
| 150 | +
|
| 151 | +### **Step 3: Examples** |
| 152 | +
|
| 153 | +#### **Example 1:** |
| 154 | +Input: |
| 155 | +```plaintext |
| 156 | +n = 4 |
| 157 | +maze = [ |
| 158 | + [1, 0, 0, 0], |
| 159 | + [1, 1, 0, 1], |
| 160 | + [1, 1, 0, 0], |
| 161 | + [0, 1, 1, 1] |
| 162 | +] |
| 163 | +``` |
| 164 | +Output: |
| 165 | +```plaintext |
| 166 | +["DDRDRR", "DRDDRR"] |
| 167 | +``` |
| 168 | + |
| 169 | + |
| 170 | + |
| 171 | +#### **Example 2:** |
| 172 | +Input: |
| 173 | +```plaintext |
| 174 | +n = 3 |
| 175 | +maze = [ |
| 176 | + [1, 0, 0], |
| 177 | + [1, 1, 0], |
| 178 | + [1, 1, 1] |
| 179 | +] |
| 180 | +``` |
| 181 | +Output: |
| 182 | +```plaintext |
| 183 | +["DDR", "DRD"] |
| 184 | +``` |
| 185 | + |
| 186 | + |
| 187 | +### **Step 4: Time and Space Complexity** |
| 188 | + |
| 189 | +#### **Time Complexity:** |
| 190 | +- There are **4 possible directions** from each cell. |
| 191 | +- In the worst case, we might explore every cell in the grid. This results in **O(4^(n\*n))**. |
| 192 | +- However, pruning due to `isSafe` reduces redundant paths, so the complexity is less than the worst case. |
| 193 | + |
| 194 | +#### **Space Complexity:** |
| 195 | +- **O(n\*n):** For the visited matrix. |
| 196 | +- **O(n):** For the recursion stack (depth of the recursion tree). |
| 197 | + |
| 198 | + |
| 199 | + |
| 200 | +### **Step 5: Recommendations** |
| 201 | +1. **Practice Backtracking:** Solve similar problems like N-Queens, Word Search, and Rat in a Maze variations to strengthen understanding. |
| 202 | +2. **Optimize Pruning:** Learn to prune invalid paths earlier to improve efficiency. |
| 203 | +3. **Understand Base Cases:** Ensure base cases are well-defined to avoid infinite recursion. |
| 204 | + |
| 205 | +By mastering backtracking, you'll handle complex problems efficiently! |
0 commit comments