给定两个正整数int x,int y,代表一个x乘y的网格,现有一个机器人要从网格左上角顶点走到右下角,每次只能走一步且只能向右或向下走,返回机器人有多少种走法。保证x+y小于等于12。
测试样例:
2,2
返回:2
//最简洁的动态规划
import java.util.*;
public class Robot {
public int countWays(int x, int y) {
// write code here
int[][] dp = new int[x][y];
for (int i = 0; i < x; i++) {
for (int j = 0; j < y; j++) {
if (i == 0 || j == 0) {
dp[i][j] = 1;
}else {
dp[i][j] = dp[i-1][j]+dp[i][j-1];
}
}
}
return dp[x-1][y-1];
}
} import java.util.*;
public class Robot {
public int countWays(int x, int y) {
// write code here
if(x==1||y==1) return 1;
return countWays(x-1,y)+countWays(x,y-1);
}
} | | |
import java.util.*;
public class Robot {
public int countWays(int x, int y) {
int[][] dp=new int[x][y];
dp[0][0]=1;
for(int i=1;i<x;i++){
dp[i][0]=1;
}
for(int i=1;i<y;i++){
dp[0][i]=1;
}
for(int i=1;i<x;i++){
for(int j=1;j<y;j++){
dp[i][j]=dp[i-1][j]+dp[i][j-1];
}
}
return dp[x-1][y-1];
}
}
//难点在于题目的理解
//方法一:递归
//方法二:滚动数组
import java.util.*;
public class Robot {
public int countWays(int x, int y) {
// write code here
//return x*y+(int)Math.pow(2,(x-1)*(y-1));
if(x==1 || y==1){
return 1;
}
return countWays(x-1, y)+countWays(x, y-1);
}
}
import java.util.*;
public class Robot {
public int countWays(int x, int y) {
// write code here
int out[]=new int[y+1];//滚动数组,降二维为一维
out[0]=0;
for(int i=1;i<y+1;i++){
out[i]=out[i]+1;
}
if(x==1||y==1)
return out[Math.max(x,y)];
for(int i=2;i<x+1;i++){
for(int j=2;j<y+1;j++){
out[j]=out[j-1]+out[j];
}
}
return out[y];
}
}
public class Robot {
public int countWays(int x, int y) {
if ( x==1 || y==1 )
return 1;
return countWays(x-1,y)+countWays(x,y-1);
}
}
/**
* DFS的思路
*/
import java.util.*;
public class Robot {
private int[][] direction = {
{0, 0}, {0, 1}, {1, 0}
};
public int countWays(int x, int y) {
// write code here
boolean[][] book = new boolean[x][y];
int[] res = new int[1];
HashSet<String> set = new HashSet<String>();
StringBuilder sBuilder = new StringBuilder();
dfs(0, 0, x - 1, y - 1, book, res, set, sBuilder);
return res[0];
}
public void dfs(int stx, int sty, int edx, int edy, boolean[][] book, int[] res, HashSet<String> set, StringBuilder sBuilder) {
if (stx > edx || sty > edy) {
return;
}
if (stx == edx && sty == edy) {
if (!set.contains(sBuilder.toString()) && sBuilder.toString().split(";").length == (edx + edy + 1)) {
res[0] ++;
set.add(sBuilder.toString());
}
} else {
for (int i = 0; i < 3; i ++) {
int nextX = stx + direction[i][0];
int nextY = sty + direction[i][1];
if (nextX >= 0 && nextX <= edx && nextY >= 0 && nextY <= edy && !book[nextX][nextY]) {
book[nextX][nextY] = true;
String pair = nextX + "," + nextY + ";";
sBuilder.append(pair);
dfs(nextX, nextY, edx, edy, book, res, set, sBuilder);
int index = sBuilder.lastIndexOf(pair);
sBuilder = sBuilder.delete(index, sBuilder.length());
book[nextX][nextY] = false;
}
}
}
}
}
这个题目可以递归来解,如何递归呢?首先,我们需要一个递推公式, 对于矩阵中的格子(i, j),假设从(1, 1)到它的路径数量为path(i, j), 那么,有:
path(i, j) = path(i-1, j) + path(i, j-1)
public class Robot {
public int countWays(int x, int y) {
if(x<=0||y<=0)
return 0;
else if(x==1||y==1)
return 1;
return countWays(x-1,y)+countWays(x,y-1);
}
}
由于题目中x+y<=12,所以不必担心递归超时问题,对于每一步,只要没有走到 边缘(x==1||y==1)就会有两种选择:向下走(x-1)or 向右走(y-1),终 止条件即走到边缘,只能一直走下去,即此时只有一种走法。 class Robot { public: int countWays(int x, int y) { // write code here if(x<=0||y<=0) return 0; if(x==1||y==1) return 1; return countWays(x-1,y)+countWays(x,y-1); } };