🚀 C# Priority Queue with Memory Optimization for Pathfinding
\n\n\n## Intuition:\nTo find the minimum time to reach the bottom-right corner of a grid while considering movement penalties, we can apply an optimized pathfin
![image.png](https://assets.leetcode.com/users/images/c8f0ed37-c0f5-4901-b5d9-a84cc5cdb579_1730685761.0166764.png)\n\n\n## Intuition:\nTo find the minimum time to reach the bottom-right corner of a grid while considering movement penalties, we can apply an optimized pathfinding algorithm using a priority queue. The idea is similar to Dijkstra\'s algorithm, where the goal is to explore paths in order of their minimal cumulative time.\n\n## Approach:\n1. **Priority Queue**: Use a priority queue to always explore the current minimum time path.\n2. **Memory Matrix**: Track the minimum time needed to reach each cell to avoid re-processing paths with higher times.\n3. **Directional Movement**: Use an array to define movement directions (up, down, left, right).\n4. **Double Step Logic**: Alternate movement cost between normal and "double step" as a strategic choice.\n5. **Termination**: Stop once the bottom-right corner is reached and update the minimum time.\n\n## Complexity:\n- **Time complexity**:  \n  $$O(n \\times m \\log(n \\times m))$$ due to the priority queue operations in a grid of size `n x m`.\n\n- **Space complexity**:  \n  $$O(n \\times m)$$ for the memory matrix and priority queue storage.\n\n# Code:\n```csharp []\npublic class Solution {\n    \n    public int MinTimeToReach(int[][] moveTime) \n    {\n        int n = moveTime.Length, m = moveTime[0].Length;\n\n        var memory = new int[n,m];\n        for (int i = 0; i < n; i++)\n            for (int j = 0; j < m; j++)\n                memory[i,j] = -1;\n\n        var directions = new (int,int)[]\n        {\n            (0,1),\n            (1,0),\n            (-1,0),\n            (0,-1)\n        };\n\n        var queue = new PriorityQueue<(int,int,bool),int>();\n        queue.Enqueue((0,0,false),0);\n    \n        var minTime = int.MaxValue;\n\n        while (queue.Count > 0)\n        {\n            if (queue.TryDequeue(out var current, out int time))\n            {\n                (int i, int j, bool doubleStep) = current;\n\n                if (i == n-1 && j == m-1)\n                {\n                    minTime = Math.Min(minTime, time);\n                    continue;\n                }\n\n                if (time >= minTime)\n                    continue;\n\n                if (memory[i,j] >= 0 && memory[i,j] <= time)\n                    continue;\n\n                memory[i,j] = time;\n\n                foreach ((var xDir, var yDir) in directions)\n                {\n                    int newI = i+xDir, newJ = j+yDir;\n                    if (newI < 0 || newI >= n || newJ < 0 || newJ >= m)\n                        continue;\n                    \n                    var newTime = Math.Max(moveTime[newI][newJ], time)+(doubleStep ? 2 : 1);\n                    if (newTime < minTime)\n                        queue.Enqueue((newI, newJ, !doubleStep),newTime);\n                }\n            }\n        }\n\n        return minTime;\n    }\n}\n```
['Depth-First Search', 'Memoization', 'Queue', 'Heap (Priority Queue)', 'Shortest Path', 'C#']