算法笔记

一、动态规划

1. 框架

我自己的理解动态规划的方法本质是归纳、递推,是一种穷举的方法(只不过这种穷举比一般的暴力穷举减少许多不必要的操作)。所以动态规划有两个重点:

  1. 状态转移方程

    状态转移方程即dp函数方程,这里又要明确几点:

    (1)dp函数的自变量(即参数、或者说状态)是什么

    (2)dp函数的值代表什么

    (3)从一个状态到另一个状态有哪些选择

  2. 确定base case

    在进行递推时,显然是需要一个初始的已知结果

(1)自顶向下

<1>暴力递归

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5GbVzsjw-1616289657177)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1613983497588.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6QwR6YH8-1616289657180)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1613983556730.png)]

<2>备忘录法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zRA2f2ft-1616289657182)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1613983651760.png)]

(2)自底向上

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BpqVbV0W-1616289657185)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1613984144281.png)]

2. 应用例题

(1)凑零钱问题

​ 给你 k 种⾯值的硬币,⾯值分别为 c1, c2 … ck ,每种硬 币的数量⽆限,再给⼀个总⾦额 amount ,问你最少需要⼏枚硬币凑出这个 ⾦额,如果不可能凑出,算法返回 -1 。

  1. 确定递推关系

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HrGhVTCU-1616289657187)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1613985266051.png)]

  2. 确定状态

    也就是原问题和⼦问题中变化的变量。由于硬币数量⽆ 限,所以唯⼀的状态就是⽬标⾦额 amount

  3. 确定dp含义

    当前的⽬标⾦额是 n ,⾄少需要 dp(n) 个硬 币凑出该⾦额

  4. 确定择优选择

    也就是对于每个状态,可以做出什么选择改变当 前状态。具体到这个问题,⽆论当的⽬标⾦额是多少,选择就是从⾯额列表 coins 中选择⼀个硬币,然后⽬标⾦额就会减少

  5. 明确basecase

    显然⽬标⾦额为 0 时,所需硬币数量为 0;当⽬标⾦额 ⼩于 0 时,⽆解,返回 -1

1. 暴力递归
def coinChange(coins: List[int], amount: int): 
    def dp(n): 
        # base case 
        if n == 0: return 0 
        if n < 0: return -1 
        # 求最⼩值,所以初始化为正⽆穷 
        res = float('INF') 
        for coin in coins: 
            subproblem = dp(n - coin) 
            # ⼦问题⽆解,跳过 
            if subproblem == -1: continue 
           	res = min(res, 1 + subproblem) 
        return res if res != float('INF') else -1 return dp(amount)
    
2. 带备忘录
def coinChange(coins: List[int], amount: int): 
    # 备忘录
	memo = dict() def dp(n): 
    # 查备忘录,避免重复计算 
    if n in memo: 
        return memo[n] 
    if n == 0: 
        return 0 
    if n < 0: 
        return -1 
    res = float('INF') 
	for coin in coins: 
        subproblem = dp(n - coin) 
        if subproblem == -1: continue 
        res = min(res, 1 + subproblem) 
        # 记⼊备忘录 
        memo[n] = res if res != float('INF') else -1 
        return memo[n]
    return dp(amount)

3. 自底向上

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TwvXVzWX-1616289657189)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1613985814946.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-z8h2Tw09-1616289657190)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1613985843679.png)]

(2)股票买卖问题

p[i]:第i天股票的价格

<1>买卖股票最佳时机1

只能交易一次(买入一次+卖出一次)

设:dp[ i ]为在第i天卖出股票所能获得的最大利润

则:dp[ i ] = max( dp[ i - 1] + p[ i ] - p[ i -1] , 0 )

<2>买卖股票最佳时机2

不限交易次数(但手里不能同时有多个股票)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XRGOssez-1616289657191)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1615106377867.png)]

<3>买卖股票最佳时机3

最多两次交易

<4>买卖股票最佳时机4

最多K笔交易

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-i647SJUW-1616289657192)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1615108252133.png)]

<5>买卖股票最佳时机含冷冻期

<6>买卖股票最佳时机含手续费

(3)打家劫舍问题

1.相邻的屋子不能抢

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xV9ivkpB-1616289657194)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1615109097207.png)]

2.首位也算作相邻

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JfDhSn0i-1616289657195)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1615109207026.png)]

3.房子在二叉树的节点上,相连的两个房子不能同时被抢劫

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-E9NhzSYD-1616289657195)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1615109463291.png)]

(4)背包问题

1.01背包

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QyBs75y1-1616289657196)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1615110183865.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ExokHXQM-1616289657197)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1615109895741.png)]

2.完全背包(每个物品数量任意多)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-brxlst8F-1616289657198)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1615110308680.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-a9KOdZ3h-1616289657199)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1615110405119.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TZmFBXvQ-1616289657200)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1615110508297.png)]

(5)实现计算器

(6)nSum问题

1.twoSum

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-k3yR1YoQ-1616289657201)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1615117514990.png)]

2.3sum

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-odludH4M-1616289657202)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1615118010903.png)]

(7)高楼扔鸡蛋

(8)衡量不同字符串之间的距离

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XTTbuY4m-1616289657203)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1615127126178.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QCgPaOZ1-1616289657203)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1615127151130.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MYMQb87D-1616289657204)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1615127521531.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IHLCS2kU-1616289657205)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1615130718140.png)]

(9)最长递增子序列

1.先定义dp[i]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-g0CYkLBJ-1616289657206)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1615180740470.png)]

注意,也就是这个递增序列的最后一个数字必须是nums[i],在这种情况下最长长度可以达到多大

2.basecase

dp[0] = 1

显然,只有一个数字的时候,那最大递增子序列就是其本身,长度为1

3.状态转移方程

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NJJyfB1M-1616289657207)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1615181633578.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eZ68mhVa-1616289657208)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1615181531086.png)]

注意,根据dp[i]的定义,最后返回的结果并不是dp[len(nums)-1],而应该是max(dp)

(10)最长公共子序列

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IXEdOuUq-1616289657209)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1615168296107.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wHdFGuPk-1616289657210)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1615168639954.png)]

先定义basecase:

显然,若其中一个字符串的长度为0,则其公共子序列的长度也是0,则:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tPiuuQ1e-1616289657210)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1615179429065.png)]

再定义状态转移方程:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Cmc3gGIP-1616289657211)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1615179892700.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Kg3YAx8T-1616289657212)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1615180074010.png)]

改成自底向上的方式:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-imLfB1Wn-1616289657213)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1615180279202.png)]

(11)最长回文子串

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SnisYleL-1616289657214)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1615182908339.png)]

(12)最大子数组和

注意:子序列是可以不连续的,但子数组是连续的

不方便用滑动窗口法,因为数组中含有数字,不好确定什么时候窗口的左右端滑动

与最长递增子序列类似,这道题的dp[i]定义需要注意:

不要定义成:dp[i]为nums[:i]的最大子数组和

定义成:dp[i]为:若这个子数组以nums[i]结尾,则其最大和可以达到多少

状态转移方程

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-q8jGuYfW-1616289657215)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1615184782773.png)]

basecase:

显然dp[0] = nums[0]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XSfuxHIP-1616289657216)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1615184899034.png)]

(13)接雨水问题

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wzIMoFCK-1616289657217)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1615185897562.png)]

二、回溯算法

回溯的本质也是穷举,遍历,而且复杂度很高,适当的剪枝操作是必要的

1. 框架

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-a35sIH0R-1616289657218)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1613986025100.png)]

2. 应用例题

(1)全排列

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bmQ04Ehc-1616289657219)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1613986565133.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Cj25jSok-1616289657220)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1613986587826.png)]

(3)N皇后

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4TBXnE6g-1616289657222)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1613986828328.png)]

(3)扔鸡蛋

若干层楼,若干个鸡蛋,让你算出最少的尝试次数,找到鸡蛋恰好摔不碎的那层楼

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KGQcnnvY-1616289657223)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1613987232236.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fScqMO3T-1616289657223)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1613987281001.png)]

三、BFS算法

核心思想:

  1. 用于求解中某两个结点的最短距离

  2. 如何将问题抽象成图的模型:

    (1)状态

    每个状态在图中是一个结点,不同状态之间可以相互转化(也即这两点之间有连线)

    要注意这个状态转换是单向还是双向的(也即是有向图还是无向图)

    (2)转化、联系、路径

    这在图中对应结点之间有连线

  3. 注意点

    (1)一定要用visited列表记录已经访问过得结点,否则一定超时!

    (2)不同场景下每个结点可能有不同数目的相连结点,可能每个结点的邻接结点数目是相同的,也可能不同

    (3)大While循环里,每次需要遍历当前temp集合里的所有结点,如果遇到目标则返回,否则将temp集合里 所有结点的所有邻接结点加入到一个temp1,然后temp = temp1,进行下次循环,直到temp1为空时 结束循环

// 计算从起点 start 到终点 target 的最近距离
int BFS(Node start, Node target) {
    Queue<Node> q; // 核⼼数据结构 
    Set<Node> visited; // 避免⾛回头路
    q.offer(start); // 将起点加⼊队列 
    visited.add(start); 
    int step = 0; // 记录扩散的步数
    
    while (q not empty) {
        int sz = q.size();
        /* 将当前队列中的所有节点向四周扩散 */
        for (int i = 0; i < sz; i++) {
            Node cur = q.poll(); 
            /* 划重点:这⾥判断是否到达终点 */
            if (cur is target) 
                return step;
            /* 将 cur 的相邻节点加⼊队列 */
            for (Node x : cur.adj()) 
                if (x not in visited) { 
                    q.offer(x); 
                    visited.add(x); 
                }
  		}
		/* 划重点:更新步数在这⾥ */ 
        step++; 
    } 
}

四、DFS算法

五、滑动窗口算法

1. 框架

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VrbQEJTX-1616289657224)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1615090366957.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-96RENYwp-1616289657225)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1615091965734.png)]

2. 应用例题

(1)最小覆盖子串

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fgehcYUJ-1616289657226)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1615091994971.png)]

(2)字符串排列

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5hVhHlT1-1616289657227)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1615092391713.png)]

(3)找所有字母异位词

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ofG7Y4F0-1616289657229)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1615092488786.png)]

(4)最长无重复子串

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FwS87Bga-1616289657230)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1615092583968.png)]

DFS算法

五、滑动窗口算法

1. 框架

[外链图片转存中…(img-VrbQEJTX-1616289657224)]

[外链图片转存中…(img-96RENYwp-1616289657225)]

2. 应用例题

(1)最小覆盖子串

[外链图片转存中…(img-fgehcYUJ-1616289657226)]

(2)字符串排列

[外链图片转存中…(img-5hVhHlT1-1616289657227)]

(3)找所有字母异位词

[外链图片转存中…(img-ofG7Y4F0-1616289657229)]

(4)最长无重复子串

[外链图片转存中…(img-FwS87Bga-1616289657230)]

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值