https://leetcode-cn.com/problems/unique-paths/
class Solution {
//行
private int m;
//列
private int n;
//缓存
private int[][] cache;
public int uniquePaths(int m, int n) {
cache = new int[m][n];
this.m = m;
this.n = n;
return countStep(0, 0);
}
private int countStep(int x, int y) {
if (x == m - 1 && y == n - 1) {
return 1;
}
if (areYouOk(x, y)) {
if (cache[x][y] != 0) {
return cache[x][y];
}
cache[x][y] = countStep(x + 1, y) + countStep(x, y + 1);
return cache[x][y];
}
return 0;
}
/**
* 检查是否越界
*/
private boolean areYouOk(int x, int y) {
return x >= 0 && x < m && y >= 0 && y < n;
}
//public static void main(String[] args) {
// System.out.println(new Solution().uniquePaths(3, 2));
// System.out.println(new Solution().uniquePaths(23, 12));
// //System.out.println(new Solution().uniquePaths(100, 100));
//}
}
/// Memory Search
/// Time Complexity: O(m * n)
/// Space Complexity: O(m * n)
class Solution {
public int uniquePaths(int m, int n) {
int[][] dp = new int[m][n];
return dfs(m - 1, n - 1, dp);
}
private int dfs(int x, int y, int[][] dp) {
if (x == 0 || y == 0) {
return 1;
}
if (dp[x][y] != 0) {
return dp[x][y];
}
return dp[x][y] = dfs(x - 1, y, dp) + dfs(x, y - 1, dp);
}
}
最上面一行,最左边一列初始化为1
重做往右填,重上往下填
/// Dynamic Programming
/// Time Complexity: O(m * n)
/// Space Complexity: O(m * n)
class Solution {
public int uniquePaths(int m, int n) {
int[][] dp = new int[m][n];
//填充(其实只填充最左边一列和最上面那一行就可以了)
for(int i = 0; i < m; i++){
Arrays.fill(dp[i], 1);
}
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
}
}
return dp[m - 1][n - 1];
}
}
直接递归会超时,应为有些点会被访问很多次
class Solution {
//行
private int m;
//列
private int n;
//不同路径
private int count = 0;
public int uniquePaths(int m, int n) {
this.m = m;
this.n = n;
countStep(0, 0);
return count;
}
private void countStep(int x, int y) {
if (x == m - 1 && y == n - 1) {
count++;
}
if (areYouOk(x, y)) {
countStep(x + 1, y);
countStep(x, y + 1);
}
}
/**
* 检查是否越界
*/
private boolean areYouOk(int x, int y) {
return x >= 0 && x < m && y >= 0 && y < n;
}
//public static void main(String[] args) {
// System.out.println(new Solution().uniquePaths(3, 2));
//}
}
https://leetcode-cn.com/problems/unique-paths-ii/
[[0,0],[1,1],[0,0]]
另一个同理,需要根据左边的条件来决定当前的值
class Solution {
private int m;
private int n;
public int uniquePathsWithObstacles(int[][] obstacleGrid) {
if (obstacleGrid == null || obstacleGrid.length == 0) {
return 0;
}
this.m = obstacleGrid.length;
this.n = obstacleGrid[0].length;
if (n == 0 || obstacleGrid[0][0] == 1) {
return 0;
}
int[][] dp = new int[m][n];
//全部填充1
for (int i = 0; i < m; i++) {
Arrays.fill(dp[i], 1);
}
//dp[0][0] = 1;
//根据左边那个觉得当前这个
for (int j = 1; j < n; j++) {
if (obstacleGrid[0][j] == 1) {
dp[0][j] = 0;
} else {
dp[0][j] = dp[0][j - 1];
}
}
//根据上面那个觉得当前这个
for (int i = 1; i < m; i++) {
if (obstacleGrid[i][0] == 1) {
dp[i][0] = 0;
} else {
dp[i][0] = dp[i - 1][0];
}
}
//
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
if (obstacleGrid[i][j] == 1) {
dp[i][j] = 0;
} else {
dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
}
}
}
return dp[m - 1][n - 1];
}
}
//private void printDpArr(int[][] dp) {
// for (int i = 0; i < m; i++) {
// for (int j = 0; j < n; j++) {
// System.out.print(dp[i][j] + "\t");
// }
// System.out.println();
// }
// System.out.println("");
//}
//public static void main(String[] args) {
// int[][] arr = {{0, 0, 0}, {0, 1, 0}, {0, 0, 0}};
// //1
// System.out.println(new Solution().uniquePathsWithObstacles(arr));
// int[][] arr02 = {{1}};
// //0
// System.out.println(new Solution().uniquePathsWithObstacles(arr02));
// int[][] arr03 = {{0, 1}};
// //0
// System.out.println(new Solution().uniquePathsWithObstacles(arr03));
// //[[0,0],[1,0]]
// int[][] arr04 = {{0, 0}, {1, 0}};
// //1
// System.out.println(new Solution().uniquePathsWithObstacles(arr04));
// //[[0,0],[1,1],[0,0]]
// int[][] arr05 = {{0, 0}, {1, 1}, {0, 0}};
// //0
// System.out.println(new Solution().uniquePathsWithObstacles(arr05));
//}