不同路径 (动态规划/DFS/BFS/数学)

首先有过这类题经验的同学肯定知道这道题必然需要用到动态规划

下面就讲一下我的思路:(动态规划三步走)

  1. 首先我们肯定是需要开一个二维数组来表示,即dp[ i ][ j ]来表示到达(i,j)这个点的路径总数
  2. 其次我们需要根据题意推断出动态规划方程,我们知道机器人每次只能向下或者是向右走一步,那么我们可以知道方程就是dp[ i ][ j ]=dp[i-1][ j ]+dp[ i ][j-1]   (和台阶问题一样道理,即我们走到某一步,该步肯定是由该步的上面或者左边走过来的
  3. 最后就是初始化,很明显,该方程的i和j都是数组下标,它们都不能为负数,所以只要i=0或者j=0的位置(即最上面一行和最左边一列)的值我们都设为1(因为不论要走到哪一个格子,我们只有一种走法,即一直向右走或者一直向下走)

最后给出代码

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

    for(i=1;i<m;i++)
    {
        for(j=1;j<n;j++)
        {
            dp[i][j]=dp[i-1][j]+dp[i][j-1];
        }
    }
    return dp[m-1][n-1];

}

        法2 DFS(对于该题会超时)

对于这种图的路径问题,DFS也是常见的做法

很明显该题的DFS出口即网格的右下角的点的坐标

class Solution {
public:
int tx,ty,cn=0,nextt[2][2]={{0,1},{1,0}};
int book[100][100]={0};//记录有没有走过

void dfs(int x,int y,int m,int n)
{
	if(x==m-1&&y==n-1)//到达右下角
	{
		cn++;
		return ;
	}
	if(!book[x][y])//这个点没走过
	{
		for(int i=0;i<2;i++)//往右边或下边走
		{
		tx=x+nextt[i][0];
		ty=y+nextt[i][1];
		if(tx<0||ty<0||tx>=m||ty>=n||book[tx][ty])//越界或走过
		{
			continue;
		}
		dfs(tx,ty,m,n);
		book[tx][ty]=0;//记得恢复
		}		
	}
}
    int uniquePaths(int m, int n) {
    	dfs(0,0,m,n);
        return cn;    
    }
};

        法3 BFS

按照我们之前学习的模板来即可

class Solution {
public:
typedef pair<int, int> PII;
int uniquePaths(int m, int n) {
	int f[101][101] = { 0 };//初始化
	f[0][0] = 1;//初始化
	queue<PII> q;
	q.push({ 0, 0 });
	int dx[2] = { 1, 0 };
	int dy[2] = { 0, 1 };
	while (!q.empty())
	{
		PII t = q.front();
		q.pop();
		for (int i = 0; i < 2; i++)
		{
			int x = t.first + dx[i];
			int y = t.second + dy[i];
			if (x >= 0 && x < n && y >= 0 && y < m)
			{

				if (f[x][y] == 0)//没走过
					q.push({ x, y });
				f[x][y] += f[t.first][t.second];//将该点的上面一点 与 该点的左边一点 的路径数相加
			}
		}
	}

	return f[n - 1][m - 1];
}
};

        法4 数学

对数学敏感的同学可能会更容易想到该方法

我们在高中时期曾经学习过组合数的概念

具体思路如下

class Solution {
public:
    int uniquePaths(int m, int n) {
        long long ans = 1;
        for (int x = n, y = 1; y < m; ++x, ++y) {
            ans = ans * x / y;
        }
        return ans;
    }
};

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ZZZWWWFFF_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值