递推算法刷题

本文介绍了动态规划和递推算法的解题思路,包括确定递推状态、公式和边界条件,通过实例如墙壁涂色、爬楼梯、最短路径等问题,展示如何应用这些算法解决问题。并提供了多个代码实现,如120.三角形最小路径和、198.打家劫舍等,帮助读者深入理解这两种算法。
摘要由CSDN通过智能技术生成

递推算法及动态规划算法刷题套路

1. 根据递推状态(学习重点)
一个函数符号,外加这个函数符号的含义描述 
一般函数所对应的值,就是要求解的值
2. 确定递推公式
		确定f(x) 究竟依赖那些f(y) 的值 
3. 分析边界条件 (K0)
4. 程序实现
		对公式进行递推、循环 遍历操作  

墙壁涂色问题

给一个环形的墙壁涂颜色,颜色一共有三种,分别是红、黄、蓝 墙壁被竖直地划分成wallsize 个部分,相邻的部分颜色不能相同。请写出函数paintWallCounts, 计算出一共有多少中给房间上色的方案。

  1. 确定递推状态
    f(n, i, j) = y
  2. 确定递推公式
    f(n, i, j) = F(n, i, j) | k

70. 爬楼梯

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

746. 使用最小花费爬楼梯

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

256. 粉刷房子

假如有⼀排房⼦,共 n 个,每个房⼦可以被粉刷成红⾊、蓝⾊或者绿⾊这三种颜⾊中 的⼀种,你需要粉刷所有的房⼦并且使其相邻的两个房⼦颜⾊不能相同。 当然,因为市场上不同颜⾊油漆的价格不同,所以房⼦粉刷成不同颜⾊的花费成本也 是不同的。每个房⼦粉刷成不同颜⾊的花费是以⼀个 n x 3 的正整数矩阵 costs 来表 ⽰的。 例如, costs[0][0] 表⽰第 0 号房⼦粉刷成红⾊的成本花费; costs[1][2] 表⽰第 1 号 房⼦粉刷成绿⾊的花费,以此类推。 请计算出粉刷完所有房⼦最少的花费成本。

120. 三角形最小路径和

class Solution:
    def minimumTotal(self, triangle: List[List[int]]) -> int:
        n = len(triangle)
        dp = [[0 for _ in range(n)], [0 for _ in range(n)]]
        dp[(n - 1) % 2] = triangle[n - 1][:]
        for i in range(n-2, -1, -1):
            idx = i % 2
            pre_idx = 1 - idx
            for j in range(0,i + 1):
                dp[idx][j] = min(dp[pre_idx][j], dp[pre_idx][j + 1]) + triangle[i][j]
        
        return dp[0][0]

119. 杨辉三角 II

class Solution:
    def getRow(self, rowIndex: int) -> List[int]:
        n = rowIndex + 1
        f = [[1 for _ in range(n)], [1 for _ in range(n)]]
        for i in range(2, n):
            idx = i %  2
            pre_index =  1 - idx
            for j in range(1, i):
                f[idx][j] = f[pre_index][j] + f[pre_index][j-1]
        
        return f[rowIndex % 2]

53. 最大子序和

class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        n = len(nums)
        for i in range(1, n): nums[i] += nums[i-1]
        pre = 0
        ans = float("-inf")
        for num in nums:
            ans = max(ans, num - pre)
            pre = min(pre, num)
        return ans 

122. 买卖股票的最佳时机 II

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        ans = 0
        pre = prices[0]
        for price in prices:
            if price > pre:
                ans += price - pre
            pre = price
        return ans 

198. 打家劫舍

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

152. 乘积最大子数组

class Solution:
    def maxProduct(self, nums: List[int]) -> int:
        pre_min = pre_max = 1 
        ans = float("-inf")
        for num in nums:
            if num < 0: pre_max, pre_min = pre_min, pre_max
            pre_max = max(pre_max * num, num)
            pre_min = min(pre_min * num, num)
            ans = max(pre_max, ans)
        return ans

322. 零钱兑换

class Solution:
    def coinChange(self, coins: List[int], amount: int) -> int:
        dp = [-1] * (amount + 1)
        dp[0] = 0
        for coin in coins:
            for i in range(coin, amount + 1):
                if dp[i - coin] == -1: continue
                if dp[i] == -1 or dp[i] > dp[i - coin] + 1: dp[i] = dp[i - coin] + 1
                dp[i] = min(dp[i], dp[i-coin] + 1)
        return dp[amount]

300. 最长递增子序列

class Solution:
    def lengthOfLIS(self, nums: List[int]) -> int:
        dp = []
        for i in range(len(nums)):
            if not dp or nums[i] > dp[-1]:
                dp.append(nums[i])
            else:
                l = 0
                r = len(dp) - 1
                tmp = 0
                while l <= r:
                    mid = (l + r) // 2
                    if dp[mid] >= nums[i]:
                        tmp = mid
                        r = mid - 1
                    else: l = mid + 1
                dp[tmp] = nums[i]
        return len(dp)
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值