题目转载自:https://leetcode-cn.com/problems/unique-paths/ (如有侵权,将会删除)
分析:
刚看到题目的时候,内心os:这不就用回溯就可以做了吗,简单!
然后就有了下面的代码:
package lc.lc62;
public class FirstSolution {
public int uniquePaths(int m, int n) {
if (m == n && m == 1) {
return 1;
}
int[][] net = new int[m][n];
net[0][0] = 2;
net[m - 1][n - 1] = 3;
// 1 右 2 下
int rightRes = dfs(net, 1, 0, 0, m, n);
int leftRes = dfs(net, 2, 0, 0, m, n);
return rightRes + leftRes;
}
public int dfs(int[][] net, int direction, int x, int y, int m, int n) {
// 首先判断结果
if (direction == 1) {
// right
if (y + 1 < n) {
if (net[x][y + 1] == 3) {
return 1;
} else if (net[x][y + 1] == 2) {
return 0;
}
} else {
return 0;
}
y += 1;
} else if (direction == 2) {
// down
if (x + 1 < m) {
if (net[x + 1][y] == 3) {
return 1;
} else if (net[x + 1][y] == 2) {
return 0;
}
} else {
return 0;
}
x += 1;
}
int res = 0;
net[x][y] = 2;
res += dfs(net, 1, x, y, m, n);
res += dfs(net, 2, x, y, m, n);
net[x][y] = 0;
return res;
}
public static void main(String[] args) {
System.out.println(new FirstSolution().uniquePaths(23, 12));
}
}
然后乐呵呵滴去提交答案,然后信心满满地等着看自己提交的答案超越了多少人。
然后看到了系统提示:超出时间限制
看到这几行字,心态就崩了,啊这。
好吧,然后看了一下解答,看到解法里竟然写到动态规划,然后我想了一下,我这里的回溯其实跟动态规划的执行过程差不多的,只不过动态规划能规避一些重复计算。
动态规划解法如下:
package lc.lc62;
public class SecondSolution {
public int uniquePaths(int m, int n) {
int dp[][] = new int[m][n];
for (int i = 0; i < m; i++) {
dp[i][0] = 1;
}
for (int i = 0; i < n; i++) {
dp[0][i] = 1;
}
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
dp[i][j] = dp[i][j - 1] + dp[i - 1][j];
}
}
return dp[m - 1][n - 1];
}
public static void main(String[] args) {
System.out.println(new SecondSolution().uniquePaths(23, 12));
}
}
按照保存中间结果的思路,我们把之前用回溯法解题的中间结果也保存下来就行了
package lc.lc62;
public class FirstSolution {
// 深度优先遍历 超时,重复计算了都
public int uniquePaths(int m, int n) {
if (m == n && m == 1) {
return 1;
}
int[][] net = new int[m][n];
net[0][0] = 2;
net[m - 1][n - 1] = 3;
// 1 右 2 下
int[][] dp = new int[m][n];
int rightRes = dfs(net, 1, 0, 0, m, n, dp);
int leftRes = dfs(net, 2, 0, 0, m, n, dp);
return rightRes + leftRes;
}
public int dfs(int[][] net, int direction, int x, int y, int m, int n, int[][] dp) {
// 首先判断结果
if (direction == 1) {
// right
if (y + 1 < n) {
if (net[x][y + 1] == 3) {
return 1;
} else if (net[x][y + 1] == 2) {
return 0;
}
} else {
return 0;
}
y += 1;
} else if (direction == 2) {
// down
if (x + 1 < m) {
if (net[x + 1][y] == 3) {
return 1;
} else if (net[x + 1][y] == 2) {
return 0;
}
} else {
return 0;
}
x += 1;
}
int res = 0;
if (dp[x][y] == 0) {
net[x][y] = 2;
res += dfs(net, 1, x, y, m, n, dp);
res += dfs(net, 2, x, y, m, n, dp);
net[x][y] = 0;
dp[x][y] = res;
}
return dp[x][y];
}
public static void main(String[] args) {
System.out.println(new FirstSolution().uniquePaths(23, 12));
}
}