DP,贪心,堆和栈,二分力扣复习

DP 题目三要素:状态,转移,初始化

二维 DP:

1143. 最长公共子序列 - 力扣(LeetCode)

python 复制代码
class Solution:
    def longestCommonSubsequence(self, text1: str, text2: str) -> int:
        m, n = len(text1), len(text2)
        # dp[i][j]: text1 前 i 个字符与 text2 前 j 个字符的 LCS 长度
        # 多开一行一列的哨兵表示空串,初始化 0 恰好正确
        dp = [[0] * (n + 1) for _ in range(m + 1)]
        for i in range(1, m + 1):
            for j in range(1, n + 1):
                if text1[i - 1] == text2[j - 1]:      # 注意偏移:前 i 个的末尾是下标 i-1
                    dp[i][j] = dp[i - 1][j - 1] + 1   # 末尾配对,双方各退一格
                else:
                    dp[i][j] = max(dp[i - 1][j], dp[i][j - 1])  # 丢掉某一方的末尾,取更优
        return dp[m][n]

时空复杂度:O(mn);

一句话思路:用 dp[i][j] 表示 text1 前 i 个字符与 text2 前 j 个字符的最长公共子序列长度,并将空串对应的边界初始化为 0。遍历两个字符串,末尾字符相同时取 dp[i-1][j-1]+1,否则取 dp[i-1][j] 和 dp[i][j-1] 的较大值,最终 dp[m][n] 即为答案。

64. 最小路径和 - 力扣(LeetCode)

很清晰的讲解:leetcode-动态规划篇 64题 最小路径和_哔哩哔哩_bilibili

python 复制代码
class Solution:
    def minPathSum(self, grid: list[list[int]]) -> int:
        m,n=len(grid),len(grid[0])
        dp=[[0]*n for _ in range(m)]
        dp[0][0] = grid[0][0]
        for j in range(1,n):
            dp[0][j] = dp[0][j-1]+grid[0][j]
        for i in range(1,m):
            dp[i][0] = dp[i-1][0]+grid[i][0]
        for i in range(1,m):
            for j in range(1,n):
                dp[i][j]=min(dp[i-1][j],dp[i][j-1])+grid[i][j]
        return dp[m-1][n-1]

一维DP:

70. 爬楼梯 - 力扣(LeetCode)

python 复制代码
class Solution:
    def climbStairs(self, n: int) -> int:
        if n<=2:
            return n
        a,b = 1,2
        for _ in range(3,n+1):
            a,b = b,a+b
        return b

198. 打家劫舍 - 力扣(LeetCode)

python 复制代码
class Solution:
    def rob(self, nums: List[int]) -> int:
        prev,curv = 0,0
        for num in nums:
            prev,curv = curv,max(curv,num+prev)
        return curv

一句话总结:用滚动变量动态规划遍历每间房屋,在"不偷当前房屋(curv)"和"偷当前房屋(num + prev)"之间取较大值,最终 curv 就是不偷相邻房屋时能获得的最高金额。

上述两道一维DP的题目,时间复杂度均为O(N),空间复杂度均为O(1)。

300. 最长递增子序列 - 力扣(LeetCode)非常爱考

python 复制代码
class Solution:
    def lengthOfLIS(self, nums: list[int]) -> int:
        n=len(nums)
        dp=[1]*n
        for i in range(n):
            for j in range(i):
                if nums[j]<nums[i]:
                    dp[i]=max(dp[j]+1,dp[i])
        return max(dp)

一句话总结:用 dp[i] 表示以 nums[i] 结尾的最长递增子序列长度,每次将当前元素接在前面较小的元素之后并取最优的 dp[j]+1,最终所有 dp 值中的最大值即为答案。

贪心:

121. 买卖股票的最佳时机 - 力扣(LeetCode)

python 复制代码
class Solution:
    def maxProfit(self, prices: list[int]) -> int:
        price=inf
        profit=0
        for i in prices:
            price=min(price,i)
            profit=max(profit,i-price)
        return profit

55. 跳跃游戏 - 力扣(LeetCode)

非常清晰的讲解:跳跃游戏:别管怎么跳,只记最远能到哪 | LeetCode Hot 100 · 078_哔哩哔哩_bilibili

python 复制代码
class Solution:
    def canJump(self, nums: list[int]) -> bool:
        far = 0
        for i,t in enumerate(nums):
            if far<i:
                return False
            else:
                far = max(far,t+i)
        return True

分发糖果-sspoffer(华)

python 复制代码
# 分发糖果 - 贪心
class Solution:
    def candy(self, ratings: List[int]) -> int:
        n = len(ratings)
        candies = [1] * n  # 每个孩子至少1颗糖果,初始值保证满足下限约束
        # 从左到右:评分比左邻居高,就比左邻居多1颗
        for i in range(1, n):
            if ratings[i] > ratings[i - 1]:
                candies[i] = candies[i - 1] + 1
        # 从右到左:评分比右邻居高,取两个方向约束的较大值
        for i in range(n - 2, -1, -1):
            if ratings[i] > ratings[i + 1]:
                candies[i] = max(candies[i], candies[i + 1] + 1)
        return sum(candies)

堆和栈:

20. 有效的括号 - 力扣(LeetCode)

python 复制代码
class Solution:
    def isValid(self, s: str) -> bool:
        pairs = {')':'(',']':'[','}':'{'}
        stack=[]
        for ch in s:
            if ch in pairs:
                if not stack or stack.pop() != pairs[ch]:
                    return False
            else:
                stack.append(ch)
        # 注意此处的返回,最易漏掉
        return not stack

739. 每日温度 - 力扣(LeetCode)

python 复制代码
class Solution:
2    def dailyTemperatures(self, temperatures: list[int]) -> list[int]:
3        n=len(temperatures)
4        res=[0]*
n
5        stack=[]
6        for i,t in enumerate(temperatures):
7            while stack and t>temperatures[stack[-1]]:
8                j=stack.pop()
9                res[j]=i-
j
10            stack.append(i)
11        return res

215. 数组中的第K个最大元素 - 力扣(LeetCode)小顶堆求解,堆-heap

复制代码
# heap - 堆,heapq - 引入小顶堆
import heapq

class Solution:
    def findKthLargest(self, nums: List[int], k: int) -> int:
        heap = []
        for x in nums:
            heapq.heappush(heap,x)
            if len(heap)>k:
                heapq.heappop(heap)
        return heap[0]

二分查找:(模板)

python 复制代码
# 二分查找 - 二分查找
class Solution:
    def search(self, nums: List[int], target: int) -> int:
        lo, hi = 0, len(nums) - 1  # 闭区间 [lo, hi]
        while lo <= hi:            # 区间非空才继续
            mid = (lo + hi) // 2
            if nums[mid] == target:
                return mid
            if nums[mid] < target:
                lo = mid + 1  # 目标在右半段
            else:
                hi = mid - 1  # 目标在左半段
        return -1  # 区间为空,没找到
相关推荐
kiracrimson1 小时前
栈与队列容器:适配器、deque 与 priority_queue
开发语言·c++·适配器模式
北冥you鱼1 小时前
Go 语言 CRUD 实战:从接口设计到真实业务场景
开发语言·后端·golang
吴名氏.1 小时前
Java转AI Agent教程(第一周)让模型先跑起来
人工智能·python·ai·ai agent
Shaoshing2 小时前
LeetCode100 42.接雨水
java·算法·leetcode
郭小李2 小时前
springmvc 拦截器
java·开发语言·前端
web打印社区2 小时前
Chrome-kiosk-printing能上生产吗
开发语言·前端·javascript·chrome·websocket
域限奇点访客2 小时前
用AI生成问卷的网站怎么选?看题目录入结构、题型映射和生成后的校验
算法
大风起兮云飞扬丶2 小时前
Java——日期类
java·开发语言
Wang's Blog2 小时前
Java 项目实战:交友项目 - 联系人管理需求分析
java·开发语言·交友