IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> LeetCode刷题笔记之动态规划(持续更新) -> 正文阅读

[数据结构与算法]LeetCode刷题笔记之动态规划(持续更新)

前言

本篇博客记录本人在LeetCode上练习动态规划算法的记录,分为简单、中等、困难三个等级,每次刷题记录也都会附上时间,方便阅览。

简单

[2022/10/4 : 7道]

【509. 斐波那契数】

原题链接:https://leetcode.cn/problems/fibonacci-number/

在这里插入图片描述

代码

class Solution:
    def fib(self, n: int) -> int:
        if n < 2:
            return n
        
        a1, a2, a3 = 0, 0, 1
        for i in range(2, n + 1):
            a1, a2 = a2, a3
            a3 = a1 + a2
        return a3

【1137. 第 N 个泰波那契数】

原题链接:https://leetcode.cn/problems/n-th-tribonacci-number/
在这里插入图片描述

代码

class Solution:
    def tribonacci(self, n: int) -> int:
        if n == 0:
            return 0
        if n <= 2:
            return 1
        x, y, z = 0, 1, 1
        for i in range(3, n + 1):
            s = x + y + z
            x, y, z= y, z, s
        return s

【70. 爬楼梯】

原题链接:https://leetcode.cn/problems/climbing-stairs/
在这里插入图片描述

思路:
首先初始化,到第一层楼梯可以爬一个阶梯,有一种方式,爬第二层可以一次爬一个台阶,也可以爬两个,有两种方式。此后的第N层楼梯既可由N-2台阶爬两次,也可以由N-1层楼梯爬一个台阶获得,则递推关系式:
f ( x ) = { 1 x = 1 2 x = 2 f ( x ? 1 ) + f ( x ? 2 ) x ≥ 3 f(x)= \begin{cases} 1 & x = 1\\ 2 & x = 2\\ f(x-1)+f(x-2) & x \geq 3\\ \end{cases} f(x)=? ? ??12f(x?1)+f(x?2)?x=1x=2x3?

代码

class Solution:
    def climbStairs(self, n: int) -> int:
        if n == 1:
            return 1
        if n == 2:
            return 2
        a, b = 1, 2
        for i in range(3, n + 1):
            c = a + b
            a, b = b, c
        return c

【118. 杨辉三角】

原题链接:https://leetcode.cn/problems/pascals-triangle/
在这里插入图片描述

代码

class Solution:
    def generate(self, n) -> List[List[int]]:
        res = []
        for i in range(1, n + 1):
            tmp = [0 for _ in range(i)]
            res.append(tmp)
        for i in range(n):
            res[i][0], res[i][i] = 1, 1
        for i in range(2, n):
            for j in range(1, i):
                res[i][j] = res[i - 1][j] + res[i - 1][j - 1]
        return res

【119. 杨辉三角 II】

原题链接:https://leetcode.cn/problems/pascals-triangle-ii/
在这里插入图片描述

代码

class Solution:
    def getRow(self, n: int) -> List[int]:
        res = []
        for i in range(1, n + 2):
            tmp = [0 for _ in range(i)]
            res.append(tmp)
        for i in range(n + 1):
            res[i][0], res[i][i] = 1, 1
        for i in range(2, n + 1):
            for j in range(1, i):
                res[i][j] = res[i - 1][j] + res[i - 1][j - 1]
        
        return res[n]

【121. 买卖股票的最佳时机】

原题链接:https://leetcode.cn/problems/best-time-to-buy-and-sell-stock/
在这里插入图片描述

思路:
在一次遍历中,保存价格的最小值,再依次算当天股票价格与最低价格的差值,取最大,即买卖股票的最佳时机。

代码

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        minn = max(prices)
        profit = 0
        for i in prices:
            minn = min(i, minn)
            profit = max(i - minn, profit)
        return profit

【338. 比特位计数】

原题链接:https://leetcode.cn/problems/counting-bits/
在这里插入图片描述

思路:
1的二进制表示1,2的二进制表示10,3的二进制表示为11,4的二进制表示为100,5的二进制表示为101,5%2=1 5的二进制表示1的个数等于2的二进制表示1的个数加5%2,可以得到递推关系式: f ( x ) = f ( x / 2 ) + x % 2 f(x)=f(x/2)+x\%2 f(x)=f(x/2)+x%2

代码

class Solution:
    def countBits(self, n: int) -> List[int]:
        f = [0 for i in range(n + 1)]
        for i in range(n + 1):
            f[i] = f[i // 2] + i % 2
        return f

[2022/10/6 : 2道]

【392. 判断子序列】

原题链接:https://leetcode.cn/problems/is-subsequence/
在这里插入图片描述

思路:
本题用动态规划的方法求解,和求最大公共子序列的长度问题类似,判断所求的最大公共子序列的长度是否等于给定字符串的长度,相等则可判断该字符串为另一个字符串的子序列。递推公式为: { d p [ i ] [ j ] = d p [ i ? 1 ] [ j ? 1 ] + 1 , s [ i ] = t [ j ] d p [ i ] [ j ] = m a x ( d p [ i ] [ j ? 1 ] , d p [ i ? 1 ] [ j ] ) , s [ i ] ≠ t [ j ] \begin{cases} dp[i][j] = dp[i - 1][j - 1] + 1, & s[i] =t[j] \\ dp[i][j] = max(dp[i][j - 1], dp[i - 1][j]), & s[i] \neq t[j] \\ \end{cases} {dp[i][j]=dp[i?1][j?1]+1,dp[i][j]=max(dp[i][j?1],dp[i?1][j]),?s[i]=t[j]s[i]=t[j]?

代码:

class Solution:
    def isSubsequence(self, s: str, t: str) -> bool:
        slen = len(s)
        tlen = len(t)
        if slen > tlen:
            return False
        dp = [[0] * (tlen + 1) for _ in range(slen + 1)]
        for i in range(1, slen + 1):
            for j in range(1, tlen + 1):
                if s[i - 1] == t[j - 1]:
                    dp[i][j] = dp[i - 1][j - 1] + 1
                else:
                    dp[i][j] = max(dp[i][j - 1], dp[i - 1][j])
        
        return dp[slen][tlen] == slen

【746. 使用最小花费爬楼梯】

原题链接:https://leetcode.cn/problems/min-cost-climbing-stairs/
在这里插入图片描述

思路:
首先初始化dp数组,dp[0] = dp[1] = 0,此后爬到第n阶的最小花费可以看作爬到第n-1阶花费加上n-1的费用与爬到第n-2阶花费加上n-2的费用的最小值,递推关系式为:
d p [ i ] = { 0 0 ≤ i ≤ 1 m i n ( d p [ i ? 1 ] + c o s t [ i ? 1 ] , d p [ i ? 2 ] + c o s t [ i ? 2 ] ) i ≥ 2 dp[i]= \begin{cases} 0 & 0\leq i \leq1 \\ min(dp[i-1]+cost[i-1],dp[i-2]+cost[i-2]) & i \geq 2 \end{cases} dp[i]={0min(dp[i?1]+cost[i?1],dp[i?2]+cost[i?2])?0i1i2?

代码

class Solution:
    def minCostClimbingStairs(self, cost: List[int]) -> int:
        n = len(cost)
        dp = [0 for _ in range(n + 1)]
        dp[0] = dp[1] = 0
        for i in range(2, n + 1):
            dp[i] = min(dp[i - 2] + cost[i - 2], dp[i - 1] + cost[i - 1])
        return dp[n]

中等

[2022/10/6 : 2道]

【198. 打家劫舍】

原题链接:https://leetcode.cn/problems/house-robber/
在这里插入图片描述

思路:
声明一个二维数组 d p dp dp,维度为 ( n + 1 ) ? 2 (n+1) * 2 (n+1)?2,初始化数组元素为0。 i i i表示第 i i i个房子, d p [ i ] [ 0 ] dp[i][0] dp[i][0]表示抢劫第 i i i个房子的总价值, d p [ i ] [ 1 ] dp[i][1] dp[i][1]表示不抢劫第 i i i个房子的总价值。抢劫第 i i i个房子,则不能抢劫第 i ? 1 i-1 i?1个房子,再加上第 i i i个房子的价值。不抢劫第 i i i个房子,则总价值等于抢劫第 i ? 1 i-1 i?1个房子和不抢劫第 i ? 1 i-1 i?1个房子中的最大值。可以得到递推关系式为:
{ d p [ i ] [ 0 ] = d p [ i ] [ 1 ] = 0 i = 0 d p [ i ] [ 0 ] = d p [ i ? 1 ] [ 1 ] + n u m s [ i ? 1 ] , d p [ i ] [ 1 ] = m a x ( d p [ i ? 1 ] [ 1 ] , d p [ i ? 1 ] [ 0 ] ) 0 ≤ i ≤ n \begin{cases} dp[i][0] = dp[i][1] = 0 & i = 0 \\ dp[i][0] = dp[i - 1][1] + nums[i - 1], dp[i][1] = max(dp[i - 1][1], dp[i - 1][0]) & 0 \le i \leq n \end{cases} {dp[i][0]=dp[i][1]=0dp[i][0]=dp[i?1][1]+nums[i?1],dp[i][1]=max(dp[i?1][1],dp[i?1][0])?i=00in?

代码

class Solution:
    def rob(self, nums: List[int]) -> int:
        n = len(nums)
        dp = [[0] * 2 for _ in range(n + 1)]
        for i in range(1, n + 1):
            # 0 rob and 1 not rob
            dp[i][0] = dp[i - 1][1] + nums[i - 1]
            dp[i][1] = max(dp[i - 1][1], dp[i - 1][0])
        return max(dp[n])

【213. 打家劫舍 II】

原题链接:https://leetcode.cn/problems/house-robber-ii/
在这里插入图片描述

思路:
与上一题的唯一区别是第 1 1 1个和第 n n n个房子不能同时打劫,所以可以算 [ 1 , n ? 1 ] [1,n-1] [1,n?1]的总价值和 [ 2 , n ] [2,n] [2,n]的总价值的最大值即可。

代码

# 法1
class Solution:
    def rob(self, nums: List[int]) -> int:
        n = len(nums)
        if n == 1:
            return nums[0]
        dp1 = [[0] * 2 for _ in range(n + 1)]
        dp2 = [[0] * 2 for _ in range(n + 1)]
        for i in range(1, n):
            # 0 rob and 1 not rob
            dp1[i][0] = dp1[i - 1][1] + nums[i - 1]
            # 不偷第i个
            dp1[i][1] = max(dp1[i - 1][1], dp1[i - 1][0])
        v1 = max(dp1[n - 1])
        for i in range(2, n + 1):
            # 0 rob and 1 not rob
            dp2[i][0] = dp2[i - 1][1] + nums[i - 1]
            # 不偷第i个
            dp2[i][1] = max(dp2[i - 1][1], dp2[i - 1][0])
        v2 = max(dp2[n])
        return max(v1, v2)
# 法2
class Solution:
    def rob(self, nums: List[int]) -> int:
        n = len(nums)
        if n == 1:
            return nums[0]
        dp = [0 for _ in range(n + 1)]
        dp[0] = 0
        dp[1] = nums[0]
        for i in range(2, n):
            dp[i] = max(dp[i - 1], dp[i - 2] + nums[i - 1])
        v1 = dp[n - 1]
        dp[1] = 0
        dp[2] = nums[1]
        for i in range(3, n + 1):
            dp[i] = max(dp[i - 1], dp[i - 2] + nums[i - 1])
        v2 = dp[n]
        return max(v1, v2)

困难

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-10-08 21:07:02  更:2022-10-08 21:07:24 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 19:35:53-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码