当前位置:网站首页>Leetcode 算法面试冲刺 热题 HOT 100 刷题(300 301 309 312 322)(六十七)
Leetcode 算法面试冲刺 热题 HOT 100 刷题(300 301 309 312 322)(六十七)
2022-08-05 19:56:00 【大叔爱学习.】
文章目录
300. 最长递增子序列

知道用动态规划,不知道怎么写,看了K神答案:









下面是根据思路,自己写的:
class Solution:
def lengthOfLIS(self, nums: List[int]) -> int:
n = len(nums)
dp = [1] * n
for i in range(1, n):
for j in range(i):
if nums[i] > nums[j]:
dp[i] = max(dp[i], dp[j] + 1)
return max(dp)
还有一种方法,先跳过,二刷过来看。
301. 删除无效的括号

太难了,回头再做,先跳了
309. 最佳买卖股票时机含冷冻期






class Solution:
def maxProfit(self, prices: List[int]) -> int:
if not prices:
return 0
n = len(prices)
# f[i][0]: 手上持有股票的最大收益
# f[i][1]: 手上不持有股票,并且处于冷冻期中的累计最大收益
# f[i][2]: 手上不持有股票,并且不在冷冻期中的累计最大收益
f = [[-prices[0], 0, 0]] + [[0] * 3 for _ in range(n - 1)]
for i in range(1, n):
f[i][0] = max(f[i - 1][0], f[i - 1][2] - prices[i])
f[i][1] = f[i - 1][0] + prices[i]
f[i][2] = max(f[i - 1][1], f[i - 1][2])
return max(f[n - 1][1], f[n - 1][2])

下面是我的:
class Solution:
def maxProfit(self, prices: List[int]) -> int:
if not prices or len(prices) == 0:
return 0
n = len(prices)
dp = [[-prices[0], 0, 0]] + [[0] * 3 for _ in range(n - 1)]
for i in range(1, n):
dp[i][0] = max(dp[i - 1][0], dp[i - 1][2] - prices[i])
dp[i][1] = dp[i - 1][0] + prices[i]
dp[i][2] = max(dp[i - 1][1], dp[i - 1][2])
return max(dp[n -1][1], dp[n - 1][2])
312. 戳气球




消去型不用顺着题目去想,还是回到最后一步。只剩一个气球。那么它的子问题就是左边的区间,和右边的区间。并且这两个区间是互不影响的。
动态规划4步法:
1、确定状态
最后一步





子问题


2、转移方程

3、初始条件和边界情况

4、计算顺序

下面是我照着写的代码,这个题太难了,不会。
class Solution:
def maxCoins(self, nums: List[int]) -> int:
if not nums or len(nums) == 0:
return 0
A = [1] + nums + [1]
n = len(nums)
dp = [[0] * (n + 2) for _ in range(n + 2)]
for i in range(n + 1):
dp[i][i + 1] = 0
for length in range(3, n + 3):
for i in range(n + 2):
j = i + length - 1
if j > n + 1:
break
for k in range(i + 1, j):
dp[i][j] = max(dp[i][j], dp[i][k] + dp[k][j] + A[i] * A[k] * A[j])
return dp[0][n + 1]
322. 零钱兑换

给出不同面额的硬币以及一个总金额. 写一个方法来计算给出的总金额可以换取的最少的硬币数量. 如果已有硬币的任意组合均无法与总金额面额相等, 那么返回 -1.


直觉

所以这种题,不论我们自己怎么做设计,都会找到返例。我们该如何用动态规划的方法解决这道题呢?
动态规划4步法:
1、确定状态
是动态规划中的定海神针,类似于数学中的函数。
我们一般都需要开一个f[i] 或者 f[i][j] 的数组
确定状态需要2步:最后一步 and 子问题
最后一步


如上图所示,如果ak是最优的策略,俺么27-ak也一定是最优的策略。也就是27-ak也是最少能拼出的硬币数。
如果可以将原问题转化成一个子问题,并且规模变小了,我们就可以设置f(x)了。这里f(X)=最少用多少枚硬币拼出X。f(27)=5,最少用5枚硬币,拼出27. 所以原问题就成了求f(27)。 子问题是求f(27-ax)。
子问题

下面是递归的解法补充:
为什么要说递归的解法,在《算法通关40讲》中也提到过,DP就是递推,递推就是递归记忆化搜索。侯老师这里讲的其实也是这样,为什么我们要想最后一步,就是通过最后一步,知道递归的条件。
递归算法的问题,f(20)算了很多次,递归的问题就是重复计算非常多,导致算法的运行效率非常低下。动态规划就是可以将递归的冗余计算去掉,秘诀就是将计算结果保存下来,并且改变了计算顺序。
2、转移方程
刚才我们用的是()。但是在转移方程中,我们是用的[] 。表示一个数组,不是一个函数名了,是一个数组。
有了转移方程,我们就可以写动态规划了(其实只是解决了一大半问题)。但是我们经常忽略的问题就是初始条件和边界情况。
3、初始条件和边界情况

有了初始条件和边界情况,我们就要考虑计算顺序了,要先算哪个下标,再算哪个下标呢?
4、计算顺序
一般动态规划中,我们都是从小往大算。因为当我们算f[x]的时候,f[x-2], f[x-5], f[x-7]在前面已经算过了。而且不需要重复计算。






这里如果是贪心算法,可能第一步就是拿7块钱,但是可能第一步就错了。这里就体现了为什么叫“动态规划”,就是在不断的从无到有,并且是在不断的规划调整的。
计算f[27],不是靠感觉,而是因为算出了f[0] —> f[26]后,自然而然的从f[25], f[22], f[20]里选择最小的(最优的)。
小结:
最值型动态规划
如何写f[x],就是在化成子问题的时候,将“最少的硬币拼出更小的面值”这句话翻译出来,f[x]表示最少用多少枚硬币拼出面值x。
动态规划的优点:消除冗余,加速计算。
看着老师的代码写的:
import sys
class Solution:
def coinChange(self, coins: List[int], amount: int) -> int:
if not coins or len(coins) == 0 or amount < 0:
return -1
n = len(coins)
dp = [sys.maxsize] * (amount + 1)
dp[0] = 0
for i in range(amount + 1):
for j in range(n):
last_index = i - coins[j]
if last_index < 0 or dp[last_index] == sys.maxsize:
continue
dp[i] = min(dp[i], dp[last_index] + 1)
if dp[amount] == sys.maxsize: return -1
return dp[amount]
边栏推荐
猜你喜欢

IPv4和IPv6有什么区别

编译器工程师眼中的好代码:Loop Interchange

"The Sea of Stars" opens an "excess ticket" paid by Justin Sun for the future of mankind

如何使用Solidity和Hardhat构建你自己的NFT以及NFT交易市场

The method of connecting to the local mysql8.0.30 database in the docker container

【微信小程序】小程序应用和页面生命周期

极光推送之自定义声音踩坑记录(持续更新)

05 tp6 的数据添加 助手函数、 save、insert、strict、replace、insertGetId、insertAll《ThinkPHP6 入门到电商实战》

2022新书 | 理解深度学习,巴斯大学教授Simon J.D. Prince撰著

泰山OFFICE技术讲座:按照WORD的做法,底纹高亮边框的效果示意图
随机推荐
国产手机羡慕,中国年轻人追捧iPhone,推动苹果成最赚钱科技企业
01 thinkphp6的前期开发准备《ThinkPHP6 入门到电商实战》
方舟开服务器游戏基础管理设置
【HMS core】【FAQ】push kit、AR Engine、广告服务、扫描服务典型问题合集2
【UiPath2022+C#】UiPathExcel 和数据表
方舟生存进化下载服务器文件及搜服方法
面试题 02.07. 链表相交-双指针法
RAID磁盘阵列详解
全志V853芯片在Tina下E907启动方式的选择
SwiftUI case: custom loading animation
codeforces:D. Chip Move【dp + 逆向思维考虑】
Understand the recommendation system in one article: Recall 08: Two-tower model - online service requires offline storage of item vectors, model update is divided into full update and incremental upda
【代码解读】超详细,YOLOV5之build_targets函数解读。
esp32 bluetooth手机蓝牙控制板子自带灯熄灭
151. Reverse words in string - double pointer method
TensorFlow learning record (4): stochastic gradient descent & Keras high-level interface
C# implements the singleton pattern and implementation ideas
C#实现单例模式和实现思路
【微信小程序】小程序应用和页面生命周期
如何设置跨域隔离启用 SharedArrayBuffer