leetcode
leetcode 1601 ~ 1650
隐藏网格下的最小消耗路径

隐藏网格下的最小消耗路径

难度:

标签:

题目描述

代码结果

运行时间: 596 ms, 内存: 25.8 MB


/*
题目思路:
1. 使用Java Streams来解决这个问题,主要还是通过动态规划的思想。
2. 创建一个二维数组dp,其中dp[i][j]表示从左上角到(i,j)的最小能量消耗。
3. 初始化第一行和第一列的值,然后通过迭代填充剩余的dp数组。
*/

import java.util.stream.IntStream;

public class MinCostPathStream {
    public int minPathSum(int[][] grid) {
        int m = grid.length;
        int n = grid[0].length;
        int[][] dp = new int[m][n];

        dp[0][0] = grid[0][0];

        // 初始化第一行
        IntStream.range(1, n).forEach(j -> dp[0][j] = dp[0][j - 1] + grid[0][j]);

        // 初始化第一列
        IntStream.range(1, m).forEach(i -> dp[i][0] = dp[i - 1][0] + grid[i][0]);

        // 填充dp数组
        IntStream.range(1, m).forEach(i -> 
            IntStream.range(1, n).forEach(j -> 
                dp[i][j] = Math.min(dp[i - 1][j], dp[i][j - 1]) + grid[i][j]
            )
        );

        return dp[m - 1][n - 1];
    }

    public static void main(String[] args) {
        MinCostPathStream solution = new MinCostPathStream();
        int[][] grid = {
            {1, 3, 1},
            {1, 5, 1},
            {4, 2, 1}
        };
        System.out.println(solution.minPathSum(grid)); // 输出7
    }
}

解释

方法:

这个题解利用了DFS和Dijkstra算法的结合来寻找从起点到目标的最短路径。首先,使用DFS从初始位置开始,探索所有可以移动到的单元格,同时记录每个单元格的移动成本和标记是否为目标。然后,使用Dijkstra算法从起点开始,根据已知的成本和距离,计算到每个可达单元格的最小路径成本。如果找到目标单元格,则返回到该单元格的最小成本。

时间复杂度:

O(N + M log M)

空间复杂度:

O(N)

代码细节讲解

🦆
如何确保DFS在遍历网格时不会重复访问同一个单元格,从而导致无限循环?
在DFS过程中,每个单元格访问前会检查其成本是否为无穷大(inf),这代表该单元格尚未被访问。一旦访问一个单元格,立即更新其成本,这样即使后续DFS尝试再次访问这个单元格,由于成本已被改变,将会跳过它。这种方法确保了每个单元格只被访问一次,防止了无限循环的发生。
🦆
在DFS过程中,如果一个方向不可移动,你将其成本标记为负无穷,这对Dijkstra算法的执行有何影响?
在Dijkstra算法中,将不可移动方向的成本设为负无穷(-inf)实际上是表示这些单元格是不可达的。Dijkstra算法在更新路径成本时会检查新的路径成本是否比当前记录的成本低,如果遇到成本为负无穷的单元格,这个检查将确保这些单元格不会被加入到优先队列中。因此,这样的标记有助于防止算法尝试通过不可达的路径寻找目标。
🦆
Dijkstra算法中使用的最小堆(Min-heap)是如何确保我们总是找到当前成本最低的路径?
在Dijkstra算法中,最小堆(Min-heap)用于存储所有待处理的单元格及其到起点的距离。每次从堆中取出(pop)一个元素时,都是当前堆中拥有最小成本的单元格。这确保了每一步算法都在扩展最低成本的路径。通过这种方式,算法可以有效地找到从起点到任一点的最短路径。
🦆
在题解中提到如果目标单元格不可达则返回-1,如何从算法的执行中准确判断出目标单元格是不可达的?
在DFS过程中,如果找到目标单元格,则会记录其位置。如果DFS完成后目标单元格的位置仍然是初始设置的无穷大值(inf),这表示目标单元格不在可达区域内。在Dijkstra算法执行中,如果堆已经空了(即没有更多单元格可处理)而目标单元格尚未被访问,这同样说明目标单元格不可达。在这两种情况下,函数返回-1,表明无法到达目标单元格。

相关问题