思路四:优化dp数组的动态规划,优化数组画图就很快解决
代码
//1. 暴力递归,超时 public int uniquePathsWithObstacles(int[][] obstacleGrid) { return recur(obstacleGrid, obstacleGrid.length - 1, obstacleGrid[0].length - 1); } public int recur(int[][] obstacleGrid, int i, int j) { if (i == 0 && j == 0 && obstacleGrid[i][j] == 0) return 1; if (i < 0 || j < 0 || obstacleGrid[i][j] == 1) return 0; return recur(obstacleGrid, i - 1, j) + recur(obstacleGrid, i, j - 1); } //2.备忘录 Map<String, Integer> map = new HashMap<>(); public int uniquePathsWithObstacles(int[][] obstacleGrid) { return recur(obstacleGrid, obstacleGrid.length - 1, obstacleGrid[0].length - 1); } public int recur(int[][] obstacleGrid, int i, int j) { String key = i + "-" + j; if (map.containsKey(key)) return map.get(key); if (i == 0 && j == 0 && obstacleGrid[i][j] == 0) return 1; if (i < 0 || j < 0 || obstacleGrid[i][j] == 1) return 0; int dist = recur(obstacleGrid, i - 1, j) + recur(obstacleGrid, i, j - 1); map.put(key, dist); return dist; } //3.动态规划 public int uniquePathsWithObstacles(int[][] obstacleGrid) { //dp[i][j]表示从00到ij的所有可能性 int[][] dp = new int[obstacleGrid.length][obstacleGrid[0].length]; if (obstacleGrid[0][0] == 1) return 0; dp[0][0] = 1; for (int i = 1; i < obstacleGrid.length; i++) { if (obstacleGrid[i][0] == 1) { dp[i][0] = 0; } else { dp[i][0] = dp[i - 1][0]; } } for (int j = 1; j < obstacleGrid[0].length; j++) { if (obstacleGrid[0][j] == 1) { dp[0][j] = 0; } else { dp[0][j] = dp[0][j - 1]; } } for (int i = 1; i < obstacleGrid.length; i++) { for (int j = 1; j < obstacleGrid[0].length; j++) { if (obstacleGrid[i][j] == 0) { dp[i][j] = dp[i - 1][j] + dp[i][j - 1]; } else { dp[i][j] = 0; } } } return dp[obstacleGrid.length - 1][obstacleGrid[0].length - 1]; } //3.优化dp数组的动态规划,通过观察我们可以发现只用到了前一行和当前行的前一个,所以可以优化为一维数组 public int uniquePathsWithObstacles(int[][] obstacleGrid) { //dp[j] 表示从00到ij的所有可能性 int[] dp = new int[obstacleGrid[0].length]; if (obstacleGrid[0][0] == 1) return 0; dp[0] = 1; for (int j = 1; j < obstacleGrid[0].length; j++) { if (obstacleGrid[0][j] == 1) { dp[j] = 0; } else { dp[j] = dp[j - 1]; } } for (int i = 1; i < obstacleGrid.length; i++) { //第一列是要更新的 dp[0] = obstacleGrid[i][0] == 1 ? 0 : dp[0]; for (int j = 1; j < obstacleGrid[0].length; j++) { if (obstacleGrid[i][j] == 0) { dp[j] += dp[j - 1]; } else { dp[j] = 0; } } } return dp[obstacleGrid[0].length - 1]; }
不同路径II