1. 问题描述:
有一个X*Y的网格,一个机器人只能走格点且只能向右或向下走,要从左上角走到右下角。
请设计一个算法,计算机器人有多少种走法
给定两个正整数int x,int y,请返回机器人的走法数目,保证x+y小于等于12
2. 一开始的时候很正常都是没有思路的,所以把问题想得很复杂那么但是越复杂的时候我们越需要冷静,这个时候我们就需要使用一些简单的例子帮助我们来分析问题,因为这些简单的问题在某些情况下可以把大的问题分解成更小的问题直到最后有了解决问题的方案
我们一开始可以画出一个1 * 1的方格,那么很容易观察得到只有一种走法,我们可以画出1 * 2, 2 * 1, 2 * 2的方格...
1 * 1: 一种走法
1 * 2:一种走法
2 * 1:一种走法
2 * 2: 两种走法
当我们处于2 * 2的方格的时候我们可以往右走一个方格,那么此时我们处于两行一列的状态,我们也可以往下走一个方格那么我们处于一行两列的情况那么1 * 2与2 * 1的走法我们原来是知道的,所以把这两种走法加起来就得到了2 * 2 方格的走法
2 * 3::三种走法:
当我们处于2 * 2的方格的时候我们可以往右走一个方格,那么此时我们处于两行两列的状态,我们也可以往下走一个方格那么我们处于一行三列的情况那么2 * 2与1 * 3的情况我们原来是知道的,所以把这两种走法加起来就得到了2 * 3 方格的走法总共有3中走法
....
那么后面的例子也是这样来分析,这样我们分析出来f(x , y) = f(x - 1, y) + f(x , y - 1)(因为只能向右走和向下走)
所以我们可以使用递归的方式来解决这个问题,其次我们也可以使用递推的方式来解决,因为涉及到两个变量都在变化,使用一维的变量是不能够保存的,所以要使用二维的数据结构:二维数组来保存其中的临时的值, x 和 y确定一个值
使用递归的话那么会消耗一定栈空间,因为每次调用一个方法那么都会开辟一个栈空间来保存临时的变量,但是代码写起来会非常的简洁,使用递推的方式有时候可以节约一定的空间,效率有时候会比递归的方式来解决要高很多,因为有可能只开辟一些很小的空间来存储变量,但是代码会比较多一点。这两种方法都可以锻炼程序员逻辑思维的养成,所以来说是比较好的
3. 递归和递推的方式来具体的代码如下:
import java.util.Scanner;
public class Main{
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int x = sc.nextInt();
int y = sc.nextInt();
int res = solve(x, y);
System.out.println(res);
res = solve1(x, y);
System.out.println(res);
sc.close();
}
private static int solve(int x, int y){
//使用递归的方式来解决
if(x == 1 || y == 1)return 1;
return solve(x - 1, y) + solve(x, y - 1);
}
private static int solve1(int m, int n){
int state[][] = new int [m + 1][n + 1];
//进行初始化
for(int i = 0; i <= m; i++){
state[i][1] = 1;
}
for(int i = 0; i <= n; i++){
state[1][i] = 1;
}
//从第二行与第二列进行填充
for(int i = 2; i <= m; i++){
for(int j = 2; j <= n; j++){
state[i][j] = state[i - 1][j] + state[i][j - 1];
}
}
return state[m][n];
}
}