LeetCode63. 不同路径 II——动态规划

题目概述

在这里插入图片描述
链接:点我做题

题解

动态规划及其优化

  本题的关键是状态转移方程,定义 f ( i , j ) f(i,j) f(i,j)为坐标(0,0)到坐标(i,j)的不同路径数目,由于只能往下走或者往右走,往下走一步后剩余路径相当于坐标 ( 0 , 0 ) (0,0) (0,0)到坐标 ( i − 1 , j ) (i-1,j) (i1,j),往右走一步后剩余路径相当于坐标 ( 0 , 0 ) (0,0) (0,0)到坐标 ( i , j − 1 ) (i,j-1) (i,j1),再考虑上阻碍的问题,状态转移方程为:
f ( i , j ) = f ( i − 1 , j ) + f ( i , j − 1 ) , i f ( o b s t a c l e G r i d ( i , j ) ! = 0 ) f ( i , j ) = 0 , e l s e 初 始 条 件 f ( 0 , 0 ) = ( o b s t a c l e G r i d ( 0 , 0 ) = = 0 ) f ( 0 , i ) = ( o b s t a c l e G r i d ( 0 , 0 ) = = 0 ) & & ( o b s t a c l e G r i d ( 0 , 1 ) = = 0 ) & & . . . & & ( o b s t a c l e G r i d ( 0 , i − 1 ) = = 0 ) f(i,j)=f(i-1,j)+f(i,j-1),if(obstacleGrid(i,j)!=0)\\ f(i,j)=0,else\\ 初始条件\\ f(0,0)=(obstacleGrid(0,0)==0)\\ f(0,i)=(obstacleGrid(0,0)==0)\&\&(obstacleGrid(0,1)==0)\\\&\&...\&\&(obstacleGrid(0,i-1)==0)\\ f(i,j)=f(i1,j)+f(i,j1),if(obstacleGrid(i,j)!=0)f(i,j)=0,elsef(0,0)=(obstacleGrid(0,0)==0)f(0,i)=(obstacleGrid(0,0)==0)&&(obstacleGrid(0,1)==0)&&...&&(obstacleGrid(0,i1)==0)
  观察到假如外层遍历i,内层遍历j时,求j的值只与上一轮i循环求得 f ( i − 1 , j ) f(i-1,j) f(i1,j)的值和这一轮遍历j是上一次求得值 f ( i , j − 1 ) f(i,j-1) f(i,j1)有关,所以可以直接用一个一维数组储存上一轮外层遍历计算的j的状态。
  并且发现这个数组的元素个数等于内层循环遍历的次数,所以可以比较m和n的大小,如果m小就让m在内层遍历,如果n小就让n在内层遍历:

class Solution {
public:
    int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) 
    {
        int m = obstacleGrid.size();
        int n = obstacleGrid[0].size();
        int ret;
        if (n < m)
        {
            vector<int> dp(n);
            dp[0] = (obstacleGrid[0][0] == 0);
            for (int i = 0; i < m; ++i)
            {
                for (int j = 0; j < n; ++j)
                {
                    if (obstacleGrid[i][j] == 1)
                    {
                        dp[j] = 0;
                    }
                    else
                    {
                        dp[j] = dp[j] + (j - 1 >= 0 ?
                         dp[j - 1] : 0);
                    }
                }
            }
            ret = dp.back();
        }
        else
        {
            vector<int> dp(m);
            dp[0] = (obstacleGrid[0][0] == 0);
            for (int i = 0; i < n; ++i)
            {
                for (int j = 0; j < m; ++j)
                {
                    if (obstacleGrid[j][i] == 1)
                    {
                        dp[j] = 0;
                    }
                    else
                    {
                        dp[j] = dp[j] + 
                        (j - 1 >= 0 ? dp[j - 1] : 0);
                    }
                }
            }
            ret = dp.back();
        }
        return ret;
    }
};

时间复杂度; O ( m ∗ n ) O(m*n) O(mn)
空间复杂度: O ( m i n ( m , n ) ) O(min(m,n)) O(min(m,n))

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值