给定一个m×n的网格,每个格子上包含一个非负整数。在网格上移动时,每次只能向下或者向右移动一步。请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。 请用分支限定法解决此问题,使用java语言,样列1: 输入:grid = [[1,3,1],[1,5,1],[4,2,1]] 输出:7 解释:因为路径 1→3→1→1→1 的总和最小。
时间: 2024-03-19 11:43:35 浏览: 128
好的,这个问题可以使用分支限定法来解决。下面是Java代码实现:
```java
import java.util.*;
public class MinPathSum {
public int minPathSum(int[][] grid) {
int m = grid.length;
int n = grid[0].length;
// 初始化起点和终点
Point start = new Point(0, 0, grid[0][0]);
Point end = new Point(m - 1, n - 1, 0);
// 使用优先队列保存状态
PriorityQueue<Point> queue = new PriorityQueue<>();
queue.offer(start);
while (!queue.isEmpty()) {
Point curr = queue.poll();
if (curr.x == end.x && curr.y == end.y) {
return curr.sum;
}
// 向下移动
if (curr.x < m - 1) {
Point down = new Point(curr.x + 1, curr.y, curr.sum + grid[curr.x + 1][curr.y]);
queue.offer(down);
}
// 向右移动
if (curr.y < n - 1) {
Point right = new Point(curr.x, curr.y + 1, curr.sum + grid[curr.x][curr.y + 1]);
queue.offer(right);
}
}
return -1; // 无解
}
// 定义状态类
static class Point implements Comparable<Point> {
int x; // 行号
int y; // 列号
int sum; // 累计和
public Point(int x, int y, int sum) {
this.x = x;
this.y = y;
this.sum = sum;
}
public int compareTo(Point other) {
return this.sum - other.sum;
}
}
// 测试
public static void main(String[] args) {
int[][] grid = {{1,3,1},{1,5,1},{4,2,1}};
MinPathSum solution = new MinPathSum();
int minSum = solution.minPathSum(grid);
System.out.println(minSum); // 输出7
}
}
```
这段代码中,我们使用了一个优先队列来保存状态,每次取出当前累计和最小的状态进行扩展。在扩展时,我们只考虑向下或向右移动的情况,并计算累计和。最后,当我们扩展到终点时,就找到了一条从左上角到右下角的路径,使得路径上的数字总和为最小。
在这个样例中,最小路径和为7,路径为1→3→1→1→1。
阅读全文