力扣:动态规划简单题集解

这篇具有很好参考价值的文章主要介绍了力扣:动态规划简单题集解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

动态规划

解题固定步骤

一般,只要解决问题的阶段、状态和状态转移决策确定了,就可以写出状态转移方程(包括边界条件)。
根据动态规划的三大基本要素可以设计解题步骤如下:

  • 状态定义: 每个状态的决策,存放每个状态的变量,

  • 状态转移方程: 当前状态与上一个状态之间的关系

  • 初始状态: 初始的状态或者边界条件

    不太熟动态规划的话一定要在草稿纸上写出初始状态,然后再慢慢递推,找出状态转移方程。

    套路写多了就会了

198. 打家劫舍

198. 打家劫舍 题目链接

你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警

给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。

class Solution {
    public int rob(int[] nums) {
        int k=0;
        int[] dp=new int[nums.length];
        dp[0]=nums[0]; //基本条件
        if(nums.length==1)
        {
            return dp[0];
        }
        dp[1]=Math.max(nums[0],nums[1]);//基本条件
        if(nums.length==2)
        {
            return dp[1];
        }

        for(int i=2;i<nums.length;i++)
        {
            //动态转移方程
            //第一种情况:不偷当前房屋,还是前一个房屋的最大值
            //第二种情况:偷当前房屋,再加上前两个房屋的最大值
            dp[i]=Math.max(dp[i-1],dp[i-2]+nums[i]);
            									
        }
        return dp[nums.length-1];
    }
}

213. 打家劫舍 II

213. 打家劫舍 II 题目链接

你是一个专业的小偷,计划偷窃沿街的房屋,每间房内都藏有一定的现金。这个地方所有的房屋都 围成一圈 ,这意味着第一个房屋和最后一个房屋是紧挨着的。同时,相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警

给定一个代表每个房屋存放金额的非负整数数组,计算你 在不触动警报装置的情况下 ,今晚能够偷窃到的最高金额。

解题思路

​ 这题比上一题多了个环型条件,为了方便起见,把环型问题转化成两个直线问题,最后比较出结果

class Solution {
    public int rob(int[] nums) {
        if(nums.length==1)
        {
            return nums[0];
        }else if(nums.length==2)
        {
            return Math.max(nums[0],nums[1]);
        }
        //把环型问题转化成两个直线问题
        int[] dp1=new int[nums.length-1]; //不包含尾
        int[] dp2=new int[nums.length];  //不包含头
        //基本条件
        dp1[0]=nums[0];
        dp1[1]=Math.max(nums[0],nums[1]);

        for(int i=2;i<nums.length-1;i++)
        {
            dp1[i]=Math.max(dp1[i-1],dp1[i-2]+nums[i]);
        }

        dp2[0]=0;
        dp2[1]=nums[1];
        dp2[2]=Math.max(nums[1],nums[2]);

        for(int i=3;i<nums.length;i++)
        {
            dp2[i]=Math.max(dp2[i-1],dp2[i-2]+nums[i]);
        }
        int m=Math.max(dp1[nums.length-2],dp2[nums.length-1]);
        return m;
    }
}

121. 买卖股票的最佳时机

121. 买卖股票的最佳时机 题目链接

给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。

你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。

返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 0

class Solution {
    public int maxProfit(int[] prices) {
        int n=prices.length;
        int[] dp1=new int[n]; //前i天买入最小值
        int[] dp2=new int[n];  //前i天收入最大值
        //基本条件
        dp1[0]=prices[0];
        dp2[0]=0;
        for(int i=1;i<n;i++)
        {
            dp1[i]=Math.min(dp1[i-1],prices[i]);
            dp2[i]=Math.max(dp2[i-1],prices[i]-dp1[i-1]);
        }
        return dp2[n-1];
    }
}

746. 使用最小花费爬楼梯

746. 使用最小花费爬楼梯 题目链接

给你一个整数数组 cost ,其中 cost[i] 是从楼梯第 i 个台阶向上爬需要支付的费用。一旦你支付此费用,即可选择向上爬一个或者两个台阶。

你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。

请你计算并返回达到楼梯顶部的最低花费。

示例 1:

力扣:动态规划简单题集解,力扣刷题集,动态规划,算法

输入:grid = [[1,3,1],[1,5,1],[4,2,1]]
输出:7
解释:因为路径 1→3→1→1→1 的总和最小。

解题思路

题目说可以从下标0或者下标1开始,为了方便起见,我用了两个dp数组,dp[]从楼梯0开始,dp1[]从楼梯1开始。

最后比较两种哪个花费小,得出结果

class Solution {
    public int minCostClimbingStairs(int[] cost) {
          int n=cost.length+1;//+1的原因是,题目就要求走到楼梯顶部,而不是最后一个楼梯
          int[] dp=new int[n];
          //初始状态
          dp[0]=0;
          dp[1]=cost[0];
          for(int i=2;i<n;i++)
          {
              
              dp[i]=Math.min(cost[i-1]+dp[i-1],cost[i-2]+dp[i-2]);
          }
          
          int[] dp1=new int[n];
          //初始状态
          dp1[0]=0;
          dp1[1]=0;
          dp1[2]=cost[1];

          for(int i=3;i<n;i++)
          {
              dp1[i]=Math.min(cost[i-1]+dp1[i-1],cost[i-2]+dp1[i-2]);
          }
          if(dp1[n-1]>dp[n-1])
              return dp[n-1];
          else
              return dp1[n-1];
    }
}

64. 最小路径和

64. 最小路径和 题目链接

给定一个包含非负整数的 *m* x *n* 网格 grid ,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。

**说明:**每次只能向下或者向右移动一步。

解题思路

第一种情况:在起点,直接等于起点
第二种情况:在最左边,只能从上面走
第三种情况:在最上面,只能从座边走
第四种情况:没有任何边界,可以从两个方向走
class Solution {
    public int minPathSum(int[][] grid) {
        int n= grid.length;
        int m= grid[0].length;
        int[][] dp=new int[n][m];

        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                if(i==0 && j==0)//在起点
                {
                    dp[i][j]=grid[i][j];
                }else if(j==0)//在最左边
                {
                    dp[i][j]=dp[i-1][j]+grid[i][j];
                }else if(i==0)//在最上面
                {
                    dp[i][j]=dp[i][j-1]+grid[i][j];
                }else{//没有边界限制
                    dp[i][j]=Math.min(dp[i-1][j]+grid[i][j],dp[i][j-1]+grid[i][j]);
                }
            }
        }
        return dp[n-1][m-1];
    }
}

后来发现可以不用创建dp数组,因为每次加完grid之后,就不用了,每个方格的元素只加过一次,所以直接在元素组grid进行操作,具体代码如下:文章来源地址https://www.toymoban.com/news/detail-721367.html

class Solution {
    public int minPathSum(int[][] grid) {
        int n= grid.length;
        int m= grid[0].length;
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                if(i==0 && j==0)//在起点
                {
                    continue;
                }else if(j==0)//在最左边
                {
                    grid[i][j]=grid[i-1][j]+grid[i][j];
                }else if(i==0)//在最上面
                {
                    grid[i][j]=grid[i][j-1]+grid[i][j];
                }else{//没有边界限制
                    grid[i][j]=Math.min(grid[i-1][j]+grid[i][j],grid[i][j-1]+grid[i][j]);
                }
            }
        }
        return grid[n-1][m-1];
    }
}

到了这里,关于力扣:动态规划简单题集解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 力扣算法刷题Day42|动态规划:01背包问题 分割等和子集

    力扣题目:01背包问题(二维数组) 刷题时长:参考题解 解题方法:动态规划 + 二维dp数组 复杂度分析 时间 空间 问题总结 理解递推公式困难 本题收获 动规思路:两层for循环,第一层i遍历物品,第二层j枚举背包容量以内所有值 确定dp数组及下标的含义:dp[i][j] 表示从下标

    2024年02月13日
    浏览(61)
  • 力扣算法刷题Day44|动态规划:完全背包问题 零钱兑换II 组合总和Ⅳ

    力扣题目:#518.零钱兑换II(完全背包组合问题) 刷题时长:7min 解题方法:动态规划(完全背包) 复杂度分析 时间复杂度: O(mn),其中 m 是amount,n 是 coins 的长度 空间复杂度: O(m) 问题总结 对递推公式的理解 本题收获 题意转换:纯完全背包是凑成背包最大价值是多少,而本

    2024年02月13日
    浏览(39)
  • 力扣刷题之旅:高级篇(六)—— 网络流算法:Edmonds-Karp 算法与实际应用

               力扣(LeetCode) 是一个在线编程平台,主要用于帮助程序员提升算法和数据结构方面的能力。以下是一些力扣上的入门题目,以及它们的解题代码。              目录 引言  一、Edmonds-Karp 算法简介 二、算法实现 下面是使用 Python 实现的 Edmonds-Karp 算法:

    2024年02月22日
    浏览(40)
  • 数据结构:力扣刷题

      给你一个  升序排列  的数组  nums  ,请你  原地  删除重复出现的元素,使每个元素  只出现一次  ,返回删除后数组的新长度。元素的  相对顺序  应该保持  一致  。然后返回  nums  中唯一元素的个数。 考虑  nums  的唯一元素的数量为  k  ,你需要做以下事情确

    2024年02月13日
    浏览(43)
  • 力扣刷题19天

             这道题下面是前提:                                           如果没有这个前提,会出现下面情况(前序遍历会变成新的树):         运行代码:           下面代码中出现的问题:         和上面那道题逻辑一样。         运行代码:          

    2024年02月04日
    浏览(44)
  • 力扣刷题 - 数组篇

    https://leetcode.cn/problems/max-consecutive-ones/ 暴力解法: 定义一个变量来统计是否连续 https://leetcode.cn/problems/teemo-attacking/ 暴力解法: 记录每次中的开始时间与结束时间, 然后如果下一次中毒的是在结束时间之前, 就去更新开始时间(让它加上这个持续时间减去结束时间),如果是在之后

    2024年02月16日
    浏览(45)
  • 力扣刷题【第一期】

    1.爬楼梯 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢? 2.求两数的和(283) 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下

    2024年02月07日
    浏览(43)
  • 【力扣刷题 | 第十五天】

    目录 前言:  ​​​​​​​63. 不同路径 II - 力扣(LeetCode) 343. 整数拆分 - 力扣(LeetCode) 总结:         本篇我们主要刷动态规划的题,解题还是严格按照我们在【夜深人静写算法】栏目下的解题步骤,大家如果没学过动态规划的可以先看看我写的动态规划文章介绍。

    2024年02月15日
    浏览(42)
  • 【力扣刷题 | 第十七天】

    目录 前言: 55. 跳跃游戏 - 力扣(LeetCode) 45. 跳跃游戏 II - 力扣(LeetCode) 总结:         今天两道类型都是贪心算法,希望可以有所收获 给定一个非负整数数组  nums  ,你最初位于数组的  第一个下标  。 数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断

    2024年02月15日
    浏览(42)
  • 【力扣刷题 | 第十三天】

    今天随机进行练习,题型上不会有什么限制,主要还是练习STL算法。 给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。 请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。 注意:最终,合并

    2024年02月10日
    浏览(52)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包