LeetCode 在矩阵中寻找路径类的动态规划问题


62 Unique Paths

题目链接:unique-paths


/**
 * 
	A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below).
	
	The robot can only move either down or right at any point in time. 
	The robot is trying to reach the bottom-right corner of the grid (marked 'Finish' in the diagram below).
	
	How many possible unique paths are there?
	
	
	Above is a 3 x 7 grid. How many possible unique paths are there?
	
	Note: m and n will be at most 100.
 *
 */

public class UniquePaths {

//	61 / 61 test cases passed.
//	Status: Accepted
//	Runtime: 173 ms
//	Submitted: 0 minutes ago
	
	//时间复杂度O(n ^ 2) 空间复杂度O(1)
    public int uniquePaths(int m, int n) {
        int[][] paths = new int[m][n];
        
        for (int i = 0; i < m; i++) 
			paths[i][n - 1] = 1;
        
        for (int i = 0; i < n - 1; i++) 
			paths[m - 1][i] = 1;
        
        for(int j = n - 2; j >= 0; j --)
        	for(int i = m - 2; i >= 0; i --)
        		paths[i][j] = paths[i + 1][j] + paths[i][j + 1];
        return paths[0][0];
    }
    
	public static void main(String[] args) {

	}

}

63 Unique Paths II

题目链接:unique-paths-ii

/**
 * 
		Follow up for "Unique Paths":
		
		Now consider if some obstacles are added to the grids. How many unique paths would there be?
		
		An obstacle and empty space is marked as 1 and 0 respectively in the grid.
		
		For example,
		There is one obstacle in the middle of a 3x3 grid as illustrated below.
		
		[
		  [0,0,0],
		  [0,1,0],
		  [0,0,0]
		]
		The total number of unique paths is 2.
		
		Note: m and n will be at most 100.
 *
 */

public class UniquePathsII {

	
//	43 / 43 test cases passed.
//	Status: Accepted
//	Runtime: 196 ms
//	Submitted: 0 minutes ago

	//时间复杂度O(m * n) 空间复杂度O(m * n)
    public int uniquePathsII(int[][] obstacleGrid) {
        int n = obstacleGrid[0].length;
        int m = obstacleGrid.length;
    	int[][] paths = new int[m][n];
    	
    	paths[m - 1][n - 1] = (obstacleGrid[m - 1][n -1] == 0) ? 1 : 0;
        
        for (int i = n - 2; i >= 0; i--) {
        	if(obstacleGrid[m - 1][i] == 1) paths[m - 1][i] = 0;
        	else paths[m - 1][i] = paths[m - 1][i + 1];
		}
        
        for (int i = m - 2; i >= 0; i--) {
        	if(obstacleGrid[i][n - 1] == 1) paths[i][n - 1] = 0;
        	else paths[i][n - 1] = paths[i + 1][n - 1];
		}
        
        for(int j = n - 2; j >= 0; j --)
        	for(int i = m - 2; i >= 0; i --) {
        		if(obstacleGrid[i][j] == 1) paths[i][j] = 0;
        		else paths[i][j] = paths[i + 1][j] + paths[i][j + 1];
        	}
        		
        return paths[0][0]; 
    }
	public static void main(String[] args) {


	}

}

64 Minimum Path Sum

题目链接:minimum-path-sum

/**
 * 
		Given a m x n grid filled with non-negative numbers, 
		find a path from top left to bottom right which minimizes the sum of all numbers along its path.
		
		Note: You can only move either down or right at any point in time.
 *
 */

public class MinimumPathSum {

	
//	61 / 61 test cases passed.
//	Status: Accepted
//	Runtime: 210 ms
//	Submitted: 0 minutes ago

	//时间复杂度O( m * n ) 空间复杂度O(1)
    public int minPathSum(int[][] grid) {
        
    	int m = grid.length;
    	if(m == 0) return Integer.MAX_VALUE;
    	
    	int n = grid[0].length;
    	
    	for(int i = n - 2; i >= 0; i --) 
    		grid[m - 1][i] += grid[m - 1][i + 1];
    	for(int i = m - 2; i >= 0; i --) 
    		grid[i][n - 1] += grid[i][n - 1];
    	
    	for(int i = m - 2; i >= 0; i--)
    		for(int j = n - 2; j >= 0; j --) 
    			grid[i][j] += Math.min(grid[i][j + 1], grid[i + 1][j]);
    	return grid[0][0];
    }
	public static void main(String[] args) {
		// TODO Auto-generated method stub

	}

}

174 Dungeon Game


题目链接: dungeon-game

/**
 * 
The demons had captured the princess (P) and imprisoned her in the bottom-right corner of a dungeon. The dungeon consists of M x N rooms laid out in a 2D grid. Our valiant knight (K) was initially positioned in the top-left room and must fight his way through the dungeon to rescue the princess.

The knight has an initial health point represented by a positive integer. If at any point his health point drops to 0 or below, he dies immediately.

Some of the rooms are guarded by demons, so the knight loses health (negative integers) upon entering these rooms; other rooms are either empty (0's) or contain magic orbs that increase the knight's health (positive integers).

In order to reach the princess as quickly as possible, the knight decides to move only rightward or downward in each step.


Write a function to determine the knight's minimum initial health so that he is able to rescue the princess.

For example, given the dungeon below, the initial health of the knight must be at least 7 if he follows the optimal path RIGHT-> RIGHT -> DOWN -> DOWN.

-2 (K)	-3	3
-5	-10	1
10	30	-5 (P)

Notes:

The knight's health has no upper bound.
Any room can contain threats or power-ups, even the first room the knight enters and the bottom-right room where the princess is imprisoned.
 *
 */

public class DungeonGame {

	//解法一
//	43 / 43 test cases passed.
//	Status: Accepted
//	Runtime: 262 ms
//	Submitted: 0 minutes ago

	//时间复杂度O( m * n ) 空间复杂度O(1)
	
	//解题思路:在原矩阵上,存储到该点所需的最少血量
	//从右下角开始计算
    public int calculateMinimumHP(int[][] dungeon) {
        int m = dungeon.length;
        int n = dungeon[0].length;
        
        //计算到the bottom-right room所需的最少血量
        if(dungeon[m - 1][n - 1] <= 0)
        	dungeon[m - 1][n - 1] = 1 - dungeon[m - 1][n - 1];
        else 
        	dungeon[m - 1][n - 1] = 1;
        //计算到达第n-1列每个房间所需的最少血量
    	for (int i = m - 2; i >= 0; i--) {
    		if(dungeon[i][n - 1] >= dungeon[i + 1][n - 1])
				dungeon[i][n - 1] = 1;
			else 
				dungeon[i][n - 1] = dungeon[i + 1][n - 1] - dungeon[i][n - 1];
		}
    	//计算到达第m-1行每个房间所需的最少血量
    	for (int i = n - 2; i >= 0; i--) {
    		if(dungeon[m - 1][i] >= dungeon[m - 1][i + 1])
				dungeon[m - 1][i] = 1;
			else 
				dungeon[m - 1][i] = dungeon[m - 1][i + 1] - dungeon[m - 1][i];
		}
    	//从右至左,从下到上,计算每个所需的最少血量
    	for(int i = m - 2; i >= 0; i--) 
    		for(int j = n - 2; j >= 0; j--){
    			int min = Math.min(dungeon[i + 1][j], dungeon[i][j + 1]);
    			if(dungeon[i][j] >= min)
    				dungeon[i][j] = 1;
    			else 
    				dungeon[i][j] = min - dungeon[i][j];
    		}
    	return dungeon[0][0];
    }
    
    //解法二
//    43 / 43 test cases passed.
//    Status: Accepted
//    Runtime: 242 ms
//    Submitted: 0 minutes ago

    
    public int calculateMinimumHP1(int[][] dungeon) {
        int m = dungeon.length;
        int n = dungeon[0].length;
        
        //计算到the bottom-right room所需的最少血量
        dungeon[m - 1][n - 1] = Math.max(1, 1 - dungeon[m - 1][n - 1]);
        //计算到达第n-1列每个房间所需的最少血量
    	for (int i = m - 2; i >= 0; i--) 
			dungeon[i][n - 1] = Math.max(1, dungeon[i + 1][n - 1] - dungeon[i][n - 1]);
    	//计算到达第m-1行每个房间所需的最少血量
    	for (int i = n - 2; i >= 0; i--) 
			dungeon[m - 1][i] = Math.max(1, dungeon[m - 1][i + 1] - dungeon[m - 1][i]);
    	//从右至左,从下到上,计算每个所需的最少血量
    	for(int i = m - 2; i >= 0; i--) 
    		for(int j = n - 2; j >= 0; j--){
    			int min = Math.min(dungeon[i + 1][j], dungeon[i][j + 1]);
    			dungeon[i][j] = Math.max(1, min - dungeon[i][j]);
    		}
    	return dungeon[0][0];
    }
    
	public static void main(String[] args) {
		// TODO Auto-generated method stub

	}

}





  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值