题目
请编写一个函数(允许增加子函数),计算n x m的棋盘格子(n为横向的格子数,m为竖向的格子数)沿着各自边缘线从右下角走到左上角,总共有多少种走法,要求不能走回头路,即:只能往左和往上走,不能往右和往下走。
思路
- 将原文题化解为子问题,若每次只能走一步,即从第(M * N)个格走一步,只有两种走法,(N – 1, M)和(N, M – 1)。由此,可将原始问题拆解成子问题。
- 边界条件: 若要走到 (0, 0)点,此时, 棋子在棋盘的最左边或者最上边的线上,只有一种走法。
即:
if (N == 0 || M == 0){ //当成为一条直线
return 1;
}
解法
- 暴力搜索
public static int solve(int N,int M){
if (N == 0 || M == 0){ //当成为一条直线
return 1;
}
return solve(N-1, M) + solve( N, M-1);
}
- 自顶向下
public class Solution02 {
//边为10*10;点为11*11
public static int[][] result;
public static int solve(int N, int M){
if (result[N][M] > 0){
return result[N][M];
}
result[N][M] = solve(N-1 , M) + solve(N, M-1);
return result[N][M];
}
public static int getStep(int N, int M){
if (N == 0 || M == 0){
return 1;
}
result = new int[N+1][M+1];
for (int i = 0; i <= N; i++){
for (int j = 0; j <= M; j++){
if (i == 0 || j == 0){
result[i][j] = 1;
}else {
result[i][j] = -1;
}
}
}
return solve(N, M);
}
public static void main(String[] args){
int N = 10;
int M = 10;
long start = System.currentTimeMillis();
System.out.println(getStep(N, M));
System.out.println("Time:"+ (System.currentTimeMillis() - start) + "ms");
}
}
- 自底向上
public class Solution03 {
public static int getStep(int N, int M){
if (N == 0 || M == 0){
return 1;
}
int[][] result = new int[N + 1][M + 1];
for (int i = 0; i <= N; i++){
for (int j = 0; j <= M; j++){
if (i == 0 || j == 0){
result[i][j] = 1;
System.out.print(result[i][j]);
}else {
result[i][j] = result[i - 1][j] + result[i][j - 1];
System.out.print(" "+result[i][j]);
}
}
System.out.print("\n");
}
return result[N][M];
}
public static void main(String[] args){
int N = 10;
int M = 10;
long start = System.currentTimeMillis();
System.out.println(getStep(N , M));
long end = System.currentTimeMillis();
System.out.println("Time:" +(end - start)+"ms");
}
}