动态规划14:一和零 不少同学刷过这道题,可能没有总结这究竟是什么背包。此时我们讲解了0-1背包的多种应用,纯 0 - 1 背包是求 给定背包容量 装满背包 的最大价值是多少。416. 分割等和子集是求 给定背包容量,能不能装满这个背包。1049. 最后一块石头的重量 II是求 给定背包容量,尽可能装,最多能装多少494. 目标和是求 给定背包容量,装满背包有多少种方法。本题是求 给定背包容量,装满背包最多有多少个物品。这些都是 0-1背包不同维度上的应用,大家可以细心体会!
动态规划:13目标和 如何转化为01背包问题呢。假设加法的总和为x,那么减法对应的总和就是sum - x。所以我们要求的是 x - (sum - x) = targetx = (target + sum) / 2**此时问题就转化为,装满容量为x的背包,有几种方法**。这里的x,就是bagSize,也就是我们后面要求的背包容量。大家看到(target + sum) / 2 应该担心计算的过程中向下取整有没有影响。这么担心就对了,例如sum 是5,target是2的话其实就是无解的,所以
动态规划:12最后一块石头的重量II 本题其实和动态规划:11分割等和子集几乎是一样的,只是最后对dp[target]的处理方式不同。动态规划:11分割等和子集相当于是求背包是否正好装满,而本题是求背包最多能装多少。
动态规划:11分割等和子集 这道题目就是一道01背包应用类的题目,需要我们拆解题目,然后套入01背包的场景。01背包相对于本题,主要要理解,题目中物品是nums[i],重量是nums[i],价值也是nums[i],背包体积是sum/2。看代码的话,就可以发现,基本就是按照01背包的写法来的。
动态规划:10 0-1背包理论基础II(滚动数组) 对于背包问题其实状态都是可以压缩的。在使用二维数组的时候,递推公式:dp[i]\[j] = max(dp[i - 1]\[j], dp[i - 1]\[j - weight[i]] + value[i]);**其实可以发现如果把dp[i - 1]那一层拷贝到dp[i]上,表达式完全可以是:dp[i]\[j] = max(dp[i]\[j], dp[i]\[j - weight[i]] + value[i]);****与其把dp[i - 1]这一层拷贝到dp[i]上,不如只用一个一维数组了**,只
动态规划:09 0-1背包理论基础I 有n件物品和一个最多能背重量为w 的背包。第i件物品的重量是weight[i],得到的价值是value[i] 。**每件物品只能用一次**,求解将哪些物品装入背包里物品价值总和最大这是标准的背包问题,以至于很多同学看了这个自然就会想到背包,甚至都不知道暴力的解法应该怎么解了。这样其实是没有从底向上去思考,而是习惯性想到了背包,那么暴力的解法应该是怎么样的呢?每一件物品其实只有两个状态,取或者不取,所以可以使用回溯法搜索出所有的情况,那么时间复杂度就是$o(2^n)$,这里的n表示物品数量。
动态规划:08不同的二叉搜索树 这道题目虽然在力扣上标记是中等难度,但可以算是困难了!首先这道题想到用动规的方法来解决,就不太好想,需要举例,画图,分析,才能找到递推的关系。然后难点就是确定递推公式了,如果把递推公式想清楚了,遍历顺序和初始化,就是自然而然的事情了。可以看出我依然还是用动规五部曲来进行分析,会把题目的方方面面都覆盖到!用动规五部曲解斐波那契的时候,感觉简答题复杂化了。但要知道,简单题是用来练习方法论的,并不能简单代码一甩,简单解释一下就完事了。可能当时不理解,现在大家应该感受方法论的重要性了,加油💪。
动态规划:07整数拆分 确定递归公式:dp[i] = max((j * (i - j)), j * dp[i - j])我们知道,要将一个数拆分的乘积最大,那么这几个数需要近似相等,那么就可以优化我们的代码。dp数组初始化:dp[0] = 0, dp[1] = 0, dp[2] = 1。确定dp数组含义:将i拆分,最大乘积是dp[i]对于思路来说,递推公式就先想到这里。debug:打印dp数组。
动态规划:06不同路径II 本题是动态规划:05不同路径的障碍版,整体思路大体一致。但就算是做过62.不同路径,在做本题也会有感觉遇到障碍无从下手。其实只要考虑到,遇到障碍dp[i][j]保持0就可以了。也有一些小细节,例如:初始化的部分,很容易忽略了障碍之后应该都是0的情况。
动态规划:03爬楼梯 所以到第三层楼梯的状态可以由第二层楼梯 和 到第一层楼梯状态推导出来,那么就可以想到动态规划了。有面试官指出:面试中能写出第一个就够了,清晰明了,如果要求进一步优化空间的话,再去优化。那么第一层楼梯再跨两步就到第三层 ,第二层楼梯再跨一步就到第三层。爬到第一层楼梯有一种方法,爬到二层楼梯有两种方法。我们发现:本题其实就是。
动态规划:01动态规划理论基础 这一篇是动态规划的整体概述,讲解了什么是动态规划,动态规划的解题步骤,以及如何debug。动态规划是一个很大的领域,今天这一篇讲解的内容是整个动态规划系列中都会使用到的一些理论基础。在后序讲解中针对某一具体问题,还会讲解其对应的理论基础,例如背包问题中的01背包,leetcode上的题目都是01背包的应用,而没有纯01背包的问题,那么就需要在把对应的理论知识讲解一下。这里理论基础篇已经是非常偏实用的了,每个知识点都是在解题实战中非常有用的内容,要重视起来。
16贪心:单调递增的数字 本题只要想清楚个例,例如98,一旦出现strNum[i - 1] > strNum[i]的情况(非单调递增),首先想让strNum[i - 1]减一,strNum[i]赋值9,这样这个整数就是89。就可以很自然想到对应的贪心解法了。想到了贪心,还要考虑遍历顺序,只有从后向前遍历才能重复利用上次比较的结果。最后代码实现的时候,也需要一些技巧,例如用一个start来标记从哪里开始赋值9。
15贪心:合并区间 所以一样的套路,先排序,让所有的相邻区间尽可能的重叠在一起,按左边界,或者右边界排序都可以,处理逻辑稍有不同。这几道题都是判断区间重叠,区别就是判断区间重叠后的逻辑,本题是判断区间重贴后要进行区间合并。本题的本质其实还是判断重叠区间问题。
14贪心:划分字母区间 在遍历的过程中相当于是要找每一个字母的边界,**如果找到之前遍历过的所有字母的最远边界,说明这个边界就是分割点了**。此时前面出现过所有字母,最远也就到这个边界了。可以分为如下两步:- 统计每一个字符最后出现的位置- 从头遍历字符,并更新字符的最远出现下标,如果找到字符最远出现位置下标和当前下标相等了,则找到了分割点