- 想象一个象棋的棋盘,
- 然后把整个棋盘放入第一象限,棋盘的最左下角是(0,0)位置
- 那么整个棋盘就是横坐标上9条线、
- 纵坐标上10条线的区域 给你三个
- 参数 x,y,k
- 返回“马”从(0,0)位置出发,必须走k步
- 最后落在(x,y)上的方法数有多少种?
解题思路:
马是走日的,那么在一个位置,他就有八个方向能走,
我们只需要递归这八个方向。然后把方法数累加就行了。
每走一步,剩余步数减一。
递归规程知道了,
下面要确认下,base case
.剩余0步时,如果此时在指定位置,就返回1,不在指定位置,代表走法不正确,返回0.
还有就是临界值检测,不能跳出棋盘,跳出棋盘,认为其走法不对,返回0;
好了,可以撸代码了:
/**
* 10 * 9 的棋盘 x 轴 是10 ,y 轴 是9
* @param a x轴上坐标
* @param b y 轴上坐标
* @param k 要走几步
* @return
*/
public static int jump(int a,int b,int k){
return process(0,0,k,a,b);
}
/**
* 递归
* @param x x位置
* @param y y位置
* @param k 步数
* @param a 要到达指定点的x轴位置
* @param b 指定点的 y 轴位置
* @return
*/
public static int process(int x,int y,int k,int a,int b){
//棋盘边缘检测,跳出棋盘,认为其当前走法是不合法的,返回0.
if (x > 9 || x < 0 || y > 8 || y < 0){
return 0;
}
//步数走完时,在指定位置,返回1,不在指定位置返回0.
if(k == 0){
return (x == a && y == b) ? 1 : 0;
}
//下面八个方向开始递归
int ways = process(x-2,y+1,k-1,a,b);
ways += process(x-1,y+2,k-1,a,b);
ways += process(x+1,y+2,k-1,a,b);
ways += process(x+2,y+1,k-1,a,b);
ways += process(x+2,y-1,k-1,a,b);
ways += process(x+1,y-2,k-1,a,b);
ways += process(x-1,y-2,k-1,a,b);
ways += process(x-2,y-1,k-1,a,b);
//八个方向的累加和 就是方法数
return ways;
}
动态规划就是对递归的改写,
三个步骤,
一.根据base case 初始化动态规划表,
二.把递归过程改成从表中拿数据的过程
三.返回值就是递归的最初始调用状态
。这个里的动态规划表三个三维数组。不过步骤是一样的,代码演示。
/**
* 动态规划
* @param a 指定位置的 x 轴位置
* @param b 指定位置的y 轴位置
* @param k 需要走K 步
* @return
*/
public static int dp(int a,int b,int k){
//动态规划表, 10 x 轴 9 y轴,K + 1 是K 步。
int[][][] dp = new int[10][9][k+1];
//base case 里 K == 0 时,a,b 位置是1,其他位置是0
dp[a][b][0] = 1;
//把递归改成从表格中拿,逻辑是一样的
for (int step = 1;step <= k;step++){
for (int x = 0;x <= 9;x++){
for (int y = 0;y <= 8;y++){
int ways = check(x-2,y+1,step-1,dp) ;
ways += check(x-1,y+2,step-1,dp);
ways += check(x+1,y+2,step-1,dp);
ways += check(x+2,y+1,step-1,dp);
ways += check(x+2,y-1,step-1,dp);
ways += check(x+1,y-2,step-1,dp);
ways += check(x-1,y-2,step-1,dp);
ways += check(x-2,y-1,step-1,dp);
dp[x][y][step] = ways;
}
}
}
//返回递归的初始状态
return dp[0][0][k];
}
/**
* 检查有没有越界,越界直接返回0
* @param x
* @param y
* @param k
* @param dp
* @return
*/
public static int check(int x,int y,int k, int[][][] dp){
if (x > 9 || x < 0 || y > 8 || y < 0){
return 0;
}
return dp[x][y][k];
}
最长回文子序列
leetcode1143. 最长公共子序列
leetcode.486. 预测赢家
数字转字符串,有多少种转化结果
背包问题–填满背包的最大价格
leetcode–N 皇后 II
凑零钱问题