class Solution {
public int fib(int n) {
if (n <= 1) return n;
int dp[] = new int[n+1];
dp[0] = 0;
dp[1] = 1;
for (int i = 2; i <= n; i++) {
dp[i] = dp[i - 1] + dp[i - 2];
}
return dp[n];
}
}
![]()
class Solution {
public int climbStairs(int n) {
if (n <= 1) return n;
int dp[] = new int[n + 1];
dp[1] = 1;
dp[2] = 2;
for (int i = 3; i <= n; i++) {
//跳一步或者跳两步就到i层了
dp[i] = dp[i - 1] + dp[i - 2];
}
return dp[n];
}
}
![]()
class Solution {
public int minCostClimbingStairs(int[] cost) {
int len = cost.length;
if (len == 0) return cost[0];
if (len == 1) return cost[0] < cost[1] ? cost[0] : cost[1];
int dp[] = new int[len + 1];
//初始化 可以从0或1开始
dp[0] = 0;
dp[1] = 0;
//递推式 min(cost[i - 1] + dp[i - 1], cost[i - 2] + dp[i - 2]);
//顶楼下标为数组长度
for (int i = 2; i <= len; i++) {
dp[i] = Math.min(cost[i - 1] + dp[i - 1], cost[i - 2] + dp[i - 2]);
}
return dp[len];
}
}
![]()
class Solution {
public int uniquePaths(int m, int n) {
int dp[][] = new int[m][n];
dp[0][0] = 1;
//第一行只能往右 j代表列
for (int j = 1; j < n; j++) {
dp[0][j] = dp[0][j - 1];
}
for (int i = 1; i < m; i++) {
dp[i][0] = dp[i - 1][0];
}
//非首行首列可往右或往下
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 {
public int uniquePathsWithObstacles(int[][] obstacleGrid) {
int m = obstacleGrid.length, n = obstacleGrid[0].length;
int dp[][] = new int[m][n];
//起点有障碍物置0
dp[0][0] = obstacleGrid[0][0] == 1? 0 : 1;
//0表示当前位置有障碍物,不可达
for (int i = 1; i < m; i++) {
if (obstacleGrid[i][0] == 1) break;
dp[i][0] = dp[i - 1][0];
}
for (int j = 1; j < n; j++) {
if (obstacleGrid[0][j] == 1) break;
dp[0][j] = dp[0][j - 1];
}
for (int i = 1; i < m; i++) {
for (int j= 1; j < n; j++) {
//必须找一条路到终点,左上都有障碍物到终点为0
if (obstacleGrid[i][j] == 1) continue;
//可以直接计数,因为前面有障碍物的置0
dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
}
}
return dp[m - 1][n - 1];
}
}
![]()
参考:programmercarl.com