【LeetCode 63】不同路径 II

基础解法
    public static int uniquePathsWithObstacles(int[][] obstacleGrid) {
    	int m = obstacleGrid.length;
    	int n = obstacleGrid[0].length;
    	if (obstacleGrid[0][0] == 1 || obstacleGrid[m-1][n-1] == 1)
    		return 0;
    	int[][] retMatrix = new int[m][n];
    	// 第一列=1
    	int ii = 0;
    	for (; ii < m; ii++)
    	{
    		if (obstacleGrid[ii][0] == 0)
    			retMatrix[ii][0] = 1;
    		else
    			break;
    	}
    	for (int t = ii; t < m; t++)
    		retMatrix[t][0] = -1;
    	// 第一行=1
    	int jj = 0;
    	for (; jj < n; jj++)
    	{
    		if (obstacleGrid[0][jj] == 0)
    			retMatrix[0][jj] = 1;
    		else
    			break;
    	}
    	for (int t = jj; t < n; t++)
    		retMatrix[0][t] = -1;
    	
    	for (int i = 1; i < m; i++)
    		for (int j = 1; j < n; j++)
    		{
    			// 本身有障碍
    			if (obstacleGrid[i][j] == 1)
    				retMatrix[i][j] = -1;
    			// 上侧和左侧都有障碍, 本身也是不可达的
    			else if (retMatrix[i-1][j] == -1 && retMatrix[i][j-1] == -1)
    				retMatrix[i][j] = -1;
    			// 上侧有障碍
    			else if (retMatrix[i-1][j] == -1)
    				retMatrix[i][j] = retMatrix[i][j-1];
    			// 左侧有障碍
    			else if (retMatrix[i][j-1] == -1)
    				retMatrix[i][j] = retMatrix[i-1][j];
    			// 上侧和左侧都没有障碍
    			else
    				retMatrix[i][j] = retMatrix[i-1][j] + retMatrix[i][j-1];
    		}
    	if (retMatrix[m-1][n-1] == -1)
    		return 0;
    	return retMatrix[m-1][n-1] ;
    }
优化解法(滚动数组)

按行滚动

    public int uniquePathsWithObstacles(int[][] obstacleGrid) {
        int n = obstacleGrid.length;
        int m = obstacleGrid[0].length; 
        int[] f = new int[m]; // 列数

        f[0] = obstacleGrid[0][0] == 0 ? 1 : 0; 

        for (int i = 0; i < n; ++i) { // 行
            for (int j = 0; j < m; ++j) { // 列
                if (obstacleGrid[i][j] == 1) { 
                    f[j] = 0;                  
                    continue;
                }
                if (j - 1 >= 0 && obstacleGrid[i][j - 1] == 0) {
                    f[j] = f[j - 1] + f[j];  // 关键步骤:其中, f[j]表示上侧的, f[j-1]表示左侧的
                }
            }
        }

        return f[m - 1];
    } 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值