算法基础例题 -- 机器人走方格

题目

有一个m*n的网格,一个机器人只能走格点且只能向右或向下走,要从左上角走到右下角。
请设计一个算法,计算机器人有多少种走法。
给定两个正整数int m,int n,请返回机器人的走法数目。保证x+y小于等于15。

思路

其实一开始拿到这种题还是很懵的,感觉无从下手。可能因为经验不足吧。
个人认为拿到这种题就应该要参数带入,先把规律找出来,从小见大。
(绘画水平有限,就不献丑了,有兴趣的自己拿个小本本画吧)
假设:

行(m),列(n) 走法
1行1列,也就是只有一个格 1种
1行2列(其实就算是n列也是一种) 1种
2行1列(n行也是一种) 1种
2行2列 2种
3行2列 3种
2行3列 3种
3行3列 不太容易看出来,但是还是可以知道是6种
.
.

规律已经浮出水面了,接下来就靠想象力了。
当我们面临 3 * 3 的时候,我们准备跨出人生中的第一步,我们是向右走呢,还是向下走呢?

但是我们会发现,无论这第一步是往下还是往右都会造成2行3列或者3行2列的结果,那么在这种局面之下,参考上表得知我们会有3种不同的结果。
那 3 * 3怎么也得至少有3+x种精彩人生吧。

继续走下去,我们会面临(2、2)—(2、1)—(1、2)—(1、1)等局面。但是我们的人生我们自己主宰啊,掏出我们的小表格,其实3 * 3就是3+2+1种走法。
虽然这规律有点不讲道理(数学不就是不讲道理的吗),但是这就是规律。
得出递归(DP)公式:f(m,n) = f((m -1), n) + f(m, (n -1))
数学:理解不了就背下来。
玩笑归玩笑,去画图吧,你将会获得数学的宽恕。

其实这是一个很有趣的规律,我们知道n行1列和1行n列其实都是只有一种走法。
那么把这些放到图里,就非常有意思了。
在这里插入图片描述
从图中可以发现:到达一个目的地的走法=到达自身左边的走法+上边的走法
这或许可以给我们一些启发。
假设我们用二维数组来代替表示地图,当我要求 3 * 3 的走法数的时候,就可以直接返回 matrix[ 2 ] [ 2 ]的值就是所求。当然为了方便,数组下标可以设为1开始。
接下来上代码,好好理解,理解不了就背下来,以后竞赛或者面试遇到这种题型直接干掉。

代码实现

public class Demo13 {
	public static void main(String[] args) {
		int m = 3;
		int n = 3;
		long time = System.currentTimeMillis();
		System.out.println(getResult(m, n));
		System.out.println( "迭代:" + (System.currentTimeMillis() - time) + "ms");
		time = System.currentTimeMillis();
		System.out.println(getResultDP(m, n));
		System.out.println("DP:" + (System.currentTimeMillis() - time) + "ms");
	}
	
	// 递归求解
	public static int getResultDP(int m, int n) {
		// 出口
		if (m == 1 || n == 1) {
			return 1;
		}
		// 直接上递推公式
		return getResultDP(m-1, n) + getResultDP(m, n-1);
	}
	
	// 迭代求解
	public static int getResult(int m, int n) {
		// 声明二维数组,为了方便理解,下标从1开始,所以大小  + 1;
		int[][] matrix = new int[m+1][n+1];
		// 把第一行全部为1(只有一行情况下,无论多少列都是只有一种走法)
		for (int i = 1; i <= m; i++) {
			matrix[i][1] = 1;
		}
		// 第一列全部为1,原理同上
		for (int i = 1; i <= n; i++) {
			matrix[1][i] = 1;
		}
		// 构建地图
		for (int i=2; i<=m; i++) {
			for (int j=2; j<=n; j++) {
				// 目标点的值 = 同一行前一列的值  + 上一行同一列的值
				matrix[i][j] = matrix[i][j-1] + matrix[i-1][j];
			}
		}
		return matrix[m][n];  // 返回最右下角的值
	}
}

运行结果
在这里插入图片描述
当数据量加大,设为 15 * 15的规模时的运行结果
在这里插入图片描述
可以看出递归和迭代的效率在本题中其实还是有很大的差距的,虽然DP的代码十分简洁,但在效率相差这么多的情况下,还是希望尽量选择迭代的方式求解。

最后

动手去画图,动手去理解,既然都已经看到最后了,说明你还是想学习这个套路或者思想的,别错过了。花个30分钟,就可以吃透了。

编程是手上功夫,别做一个走马观花的人---送给我自己
原创文章 16 获赞 4 访问量 1549

猜你喜欢

转载自blog.csdn.net/weixin_44702572/article/details/104740354
今日推荐