leetcode 力扣 62.不同路径(动态规划经典例题)

题目描述:

leetcode 力扣 62.不同路径(动态规划经典例题)_第1张图片

解题思路:

首先我们尝试着用暴力递归去解题,但是毫无疑问出现了超时无法提交成功,所以我们可以尝试一下dp
这是动态规划的一道经典例题,我们首先定义一个二维数组p[][]来表示到每个位置的路径条数,由题设我们可以看出,对于任意位置(x,y),只能由(x,y-1)向下走一步或者由位置(x-1,y)向右走一步到达,所以可以得到递推关系p[x][y]=p[x-1][y]+p[x][y-1],我们可以让p[0][0]=1,而p[m-1][n-1]就是我们要求的结果,这样做出来的时间复杂度和空间复杂度都是O(mn)

注意事项:

还有要注意的是,由于机器人只能向右或者向下,所以我们可以让p[0][i]和p[i][0]的值直接为1


代码:

int uniquePaths(int m, int n) {
    int i,j;
	int p[m][n];
    for(i=0;i<m;++i) 
	{
        p[i][0]=1;
    }
    for (j=0;j<n;++j) 
	{
        p[0][j]=1;
	}	
    for(i=1;i<m;++i) 
	{
        for(j=1;j<n;++j) 
		{
            p[i][j]=p[i-1][j]+p[i][j-1];
        }
    }
    return p[m-1][n-1];
}

运行结果:

leetcode 力扣 62.不同路径(动态规划经典例题)_第2张图片

运行结果
(力扣的运行时间大家都清楚,做一个参考就好)

解法优化:

思路:

在创建二维数组的时候会占用较大的空间,所以我们可以尝试一下将二维数组压缩成一维数组进行dp,这样空间复杂度可以降为O(n)

原理;

在每次循环中p[j]是上一次循环时j位置数组的元素值,而p[j-1]的值是左边的值,相当于把二维数组压缩为一维数组

代码:

int uniquePaths(int m, int n) {
    int i,j;
	int p[n];
    p[0] = 1;
    if(m>n)
    {
    	int t;
    	t=m;
    	m=n;
    	n=t;
    }	//交换m,n
    for(i=1;i<n;i++)
    {
    	p[i]=0;
	}
	for(i=0;i<m;i++) 
	{
        for(j=1;j<n;j++) 
		{
            p[j]+=p[j-1];
        }
    }
    return p[n-1];
}

运行结果:

在这里插入图片描述


其他解法:

同样,我们也可以用到高中数学的排列组合方法来解这道题,由于机器人一共会走m+n-2步,那么直接m+n-2中挑出m-1步向下走即可,那么最终结果就是C(m-1)(m+n-2)

代码:

int uniquePaths(int m, int n) {
    long long int path = 1;
    for (int x = n, y = 1; y < m; ++x, ++y) {
        path = path * x / y;
    }
    return path;
}

运行结果: 在这里插入图片描述


知识点:

动态规划:动态规划常是用来求最优解的一种途径,在求全局最优解的过程中,分治思想是较为常见的一种解题途径,但如果子问题之间不独立,则适合用动态规划思想。而动态规划和贪心算法的不同之处是,动态规划是针对全局求最优解,而贪心算法是针对上一个最优解继续求最优解0。同时,由于在动态规划的过程中要存储各种状态,所以会占用更多空间,是一种以空间换时间的方法。在动态规划中,核心的步骤是找到数组元素之间的关系式

你可能感兴趣的:(leetcode,动态规划,算法)