设为首页 加入收藏

TOP

LeetCode刷题第八九十周(一)
2023-07-25 21:41:51 】 浏览:78
Tags:LeetCode 八九十

动态规划

如果某一问题有很多重叠子问题,使用动态规划是最有效的

解题步骤:

背包问题:01背包,完全背包,多重背包

01背包:
统一使用一维数组来进行遍历

 public static void main(String[] args) {
        int[] weight = {1, 3, 4};
        int[] value = {15, 20, 30};
        int bagWight = 4;
        testWeightBagProblem(weight, value, bagWight);
    }

    public static void testWeightBagProblem(int[] weight, int[] value, int bagWeight){
        int wLen = weight.length;
        //定义dp数组:dp[j]表示背包容量为j时,能获得的最大价值
        int[] dp = new int[bagWeight + 1];
        //遍历顺序:先遍历物品,再遍历背包容量
        for (int i = 0; i < wLen; i++){
            for (int j = bagWeight; j >= weight[i]; j--){
                dp[j] = Math.max(dp[j], dp[j - weight[i]] + value[i]);
                //对于组合问题的递推公式为:dp[j] += dp[j - nums[i]],需要初始化dp[0]=1;
            }
        }
        //打印dp数组
        for (int j = 0; j <= bagWeight; j++){
            System.out.print(dp[j] + " ");
        }
    }

完全背包:

01背包和完全背包唯一不同就是体现在遍历顺序上,完全背包的物品是可以添加多次的,所以要从小到大去遍历
// 先遍历物品,再遍历背包
for(int i = 0; i < weight.size(); i++) { // 遍历物品
    for(int j = weight[i]; j <= bagWeight ; j++) { // 遍历背包容量
        dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);
        //对于组合问题的递推公式为:dp[j] += dp[j - nums[i]],需要初始化dp[0]=1;
    }
}
//对于排列问题,先遍历背包,再遍历物品
dp[0] = 1;
for (int j = 0; j <= amount; j++) { // 遍历背包容量
    for (int i = 0; i < coins.size(); i++) { // 遍历物品
        if (j - coins[i] >= 0) dp[j] += dp[j - coins[i]];
    }
}


509、斐波那契数

class Solution {
    public int fib(int n) {
        // if(n==1){
        //     return 1;
        // }
        // if(n==0){
        //     return 0;
        // }
        // return fib(n-1)+fib(n-2);
        if(n==1){
            return 1;
        }
        if(n==0){
            return 0;
        }
        int[] dp = new int[n+1];
        dp[0] = 0;
        dp[1] = 1;
        for(int i = 2; i < n+1; 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++){
            dp[i] = dp[i - 1] + dp[i - 2];
        }
        return dp[n];
    }
}

746、使用最小花费爬楼梯

class Solution {
    public int minCostClimbingStairs(int[] cost) {
        int[] dp = new int[cost.length + 1];
        dp[0] = 0;
        dp[1] = 0;
        for(int i = 2; i <= cost.length; i++){
            dp[i] = Math.min(dp[i - 1] + cost[i - 1],dp[i - 2] + cost[i - 2]);
        }
        return dp[cost.length];
    }
}

62、 不同路径

class Solution {
    public int uniquePaths(int m, int n) {
        int[][] dp = new int[m][n];
        dp[0][0] = 1;
        for(int i = 1; i < m; i++){
            dp[i][0] = 1;
        }
        for(int j = 1; j < n; j++){
            dp[0][j] = 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];

    }
}

63、不同路径 II

class Solution {
    public int uniquePathsWithObstacles(int[][] obstacleGrid) {
        int m = obstacleGrid.length;
        int n = obstacleGrid[0].length;
        int[][] dp = new int[m][n];
        if(obstacleGrid[0][0] == 1){
            return 0;
        }else{
            dp[0][0] = 1;
        }
        for(int i = 1; i < m; i++){
            if(obstacleGrid[i][0] == 1){
                break;
            }else{
                dp[i][0] = 1;
            }
        }
        for(int j = 1; j < n; j++){
            if(obstacleGrid[0][j] == 1){
                break;
            }else{
                dp[0][j] = 1;
            }
        }
        for(int i = 1; i < m; i++){
            for(int j = 1; j < n; j++){
                if(obstacleGrid[i][j] == 1){
                    continue;
                }else{
                    dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
                } 
            }
        }
        return dp[m - 1][n - 1];
    }
}

343、整数拆分

class Solution {
    public int integerBreak(int n) {
        // 方法一:贪心
        // if(n == 2){
        //     return 1;
        // }else if(n == 3){
        //     return 2;
        // }
        // int result = 1;
        // while(n > 0){
        //     if(n > 4){
        //         result *= 3;
        //         n = n - 3;
        //     }else if(n == 4){
        //         result *= 4;
        //         break;
        //     }else if(n == 3 || n == 2){
        //         result *= n;
        //         break;
        //     }
        // }
        // return result;
        // 方法二:动态规划
        int[] dp = new int[n];
        dp[0] = 1;
        dp[1] = 1;
        for(int i = 2; i < n; i++){
            int left = 0;
            int right = i - 1;
            while(left <= right){
                dp[i] = Math.ma
首页 上一页 1 2 3 4 5 6 下一页 尾页 1/6/6
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇别催了,别催了,这篇文章我一次.. 下一篇学习笔记——MyBatis自动映射与自..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目