1. DFS Backtracking with Pruning
Intuition
Explore all possible 4-directional simple paths from (0, 0) to (R-1, C-1). Track the maximum step difference along each path. Maintain a 2D array minEffort[r][c] to prune any branch whose current effort exceeds the best recorded effort to reach (r, c).
Algorithm
- Initialize
minEffortgrid of size R × C with infinity, setminEffort[0][0] = 0. - Define
dfs(r, c, currentMax): - If
currentMax >= minEffort[r][c], prune branch. -
minEffort[r][c] = currentMax. - If
r == R - 1 && c == C - 1, return. - For each 4-directional neighbor
(nr, nc): -
stepDiff = abs(heights[nr][nc] - heights[r][c]) -
dfs(nr, nc, max(currentMax, stepDiff)) - Return
minEffort[R-1][C-1].
#include <iostream>#include <vector>#include <algorithm>#include <cmath>#include <climits> const int dr[] = {-1, 1, 0, 0};const int dc[] = {0, 0, -1, 1}; void dfs(int r, int c, int currentEffort, const std::vector<std::vector<int>>& heights, std::vector<std::vector<int>>& minEffort) { if (currentEffort >= minEffort[r][c]) return; minEffort[r][c] = currentEffort; int R = heights.size(), C = heights[0].size(); if (r == R - 1 && c == C - 1) return; for (int i = 0; i < 4; ++i) { int nr = r + dr[i], nc = c + dc[i]; if (nr >= 0 && nr < R && nc >= 0 && nc < C) { int stepDiff = std::abs(heights[nr][nc] - heights[r][c]); dfs(nr, nc, std::max(currentEffort, stepDiff), heights, minEffort); } }} int minimumEffortPathDFS(std::vector<std::vector<int>>& heights) { int R = heights.size(), C = heights[0].size(); std::vector<std::vector<int>> minEffort(R, std::vector<int>(C, INT_MAX)); dfs(0, 0, 0, heights, minEffort); return minEffort[R - 1][C - 1];} int main() { std::vector<std::vector<int>> heights = {{1,2,2},{3,8,2},{5,3,5}}; std::cout << "Min Effort (DFS): " << minimumEffortPathDFS(heights) << std::endl; return 0;}Time & Space Complexity
- Time complexity:
O(4^(R * C)) in the worst case due to exhaustive exploration of all grid paths. - Space complexity:
O(R * C) for the recursion stack and effort matrix.