动态规划day01

509. 斐波那契数

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];
    }
}

70. 爬楼梯

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];
    }
}

746. 使用最小花费爬楼梯

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];
    }
}

62. 不同路径

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];
    }
}

63. 不同路径 II

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

posted @ 2022-06-17 21:36  一梦两三年13  阅读(21)  评论(0)    收藏  举报