算法图解笔记(附PDF下载地址)

2023-11-12

算法图解(pdf版) 链接:https://pan.baidu.com/s/1FJvija2NNmhOSpd7D3yE_g 提取码:bwcm

分治策略

分治策略(分而治之)是一种解决问题的思路,使用递归实现

工作原理

  1. 找出简单基线条件(递归中的概念,基线条件指函数不再调用自己;递归条件指函数调用自己)
  2. 缩小问题规模使接近基线条件(编写涉及数组的递归函数时,基线条件通常是数组为空或只包含一个元素。陷入困境时,请检查基线条件是不是这样的。)

代表算法:二分查找,快排

散列函数

散列表适用场景

  • 模拟映射关系
  • 防止重复
  • 数据缓存

注意的点

  • 冲突很糟糕,应使用可以最大限度减少冲突的散列函数(冲突过多会影响数据查找、删除速度;严重时会退化为链表)
  • 一旦填装因子超过0.7,就该调整散列表的长度

广度优先搜索

广度优先是一种用于图的查找算法,一般用来帮助解决两类问题:

  1. 有无路径问题(从节点A出发,有到节点B的路径吗?)
  2. 最短路径问题(从节点A触发,前往节点B哪条路径最短?)在这里插入图片描述

注意点

  • 对于寻找最短路径的问题,可尝试使用图来建立模型,再使用广度优先搜索来解决问题
  • 有向图中的边为箭头,箭头的方向指定了关系的方向
  • 无向图中的边不带箭头,其中的关系是双向的
  • 你需要按加入顺序检查搜索列表中的人,否则找到的就不是最短路径,因此搜索列表必须是队列
  • 对于检查过的人,务必不要再去检查,否则可能导致无限循环(节点间的相互引用)

狄克斯特拉算法

在介绍迪克斯特拉算法前,先介绍一些基础概念
每条边都有关联数字的图,这些数字称为权重
在这里插入图片描述
带权重的图称为加权图,不带权重的图称为非加权图
在这里插入图片描述
图中可能有环
在这里插入图片描述
狄克斯特拉算法包含4个步骤。

  1. 找出“最便宜”的节点,即可在最短时间内到达的节点
  2. 对于该节点的邻居,检查是否有前往它们的更短路径,如果有,就更新其开销
  3. 重复这个过程,直到对图中的每个节点都这样做了
  4. 计算最终路径

注意点

  • 狄克斯特拉算法只适用于有向无环图
  • 不能将狄克斯特拉算法用于包含负权边的图

小结

  • 广度优先搜索用于在非加权图中查找最短路径。
  • 狄克斯特拉算法用于在加权图中查找最短路径。
  • 仅当权重为正时狄克斯特拉算法才管用。
  • 如果图中包含负权边,请使用贝尔曼福德算法。

算法的Java实现

public class MyDijkstra {

    private static int NOWAY_SIGN = Integer.MAX_VALUE;
    private static String START = "start";
    private static String END = "end";

    public static void main(String[] args) {
        MyDijkstra dijkstra = new MyDijkstra();
        dijkstra.getMinStep();
    }

    private void getMinStep(){
        // 初始化
        Map<String, Map<String, Integer>> grapth = grapthInit();
        Map<String, Integer> costs = costInit();
        Map<String, String> parents = parentInit();
        // 判断是否检查过
        List<String> processed = new ArrayList<>(10);

        // 1. 找到start的最小开销节点
        String node = this.findLowestCostNode(costs,processed);

        // 2. 遍历该节点所有邻居并更新其开销
        while (node != null && grapth.get(node) != null){
            // 获取相邻节点
            Map<String, Integer> xianglinjiedian = grapth.get(node);

            int cost = costs.get(node);

            for (Map.Entry<String, Integer> entry : xianglinjiedian.entrySet()) {
                // 新旧开销的比较,若成功则更新
                int newCost = cost + entry.getValue();
                if(newCost < costs.get(entry.getKey()) || !costs.containsKey(entry.getKey())){
                    costs.put(entry.getKey(),newCost);
                    parents.put(entry.getKey(),node);
                }
            }
            // 加入已处理节点
            processed.add(node);
            // 找出最小开销节点
            node = this.findLowestCostNode(costs,processed);
        }
        System.out.println(parents);
        System.out.println(costs.get(END));
    }

    private String findLowestCostNode(Map<String, Integer> costs,List<String> processed){
        int lowestCost = NOWAY_SIGN;
        String lowNode = null;

        for (Map.Entry<String, Integer> entry : costs.entrySet()) {
            // 未被处理且小于mini
            if(!processed.contains(entry.getKey()) && entry.getValue() < lowestCost){
                lowestCost = entry.getValue();
                lowNode = entry.getKey();
            }
        }

        return lowNode;
    }
    
    private Map<String,String> parentInit() {
        Map<String,String> parentInit = new HashMap<>(16);
        parentInit.put("A",START);
        parentInit.put("B",END);
        parentInit.put(END,null);
        return parentInit;
    }

    private Map<String,Integer> costInit() {
        Map<String,Integer> costsMap = new HashMap<>(16);
        costsMap.put("A",6);
        costsMap.put("B",2);
        costsMap.put(END,Integer.MAX_VALUE);
        return costsMap;
    }

    // 构造有向图
    private Map<String, Map<String,Integer>> grapthInit() {
        Map<String, Map<String,Integer>> grapth = new HashMap<>(16);
        Map<String,Integer> startValue1 = new HashMap<>(2);
        startValue1.put("A",6);
        startValue1.put("B",2);
        grapth.put(START,startValue1);
        Map<String,Integer> startValue2 = new HashMap<>(2);
        startValue2.put(END,1);
        grapth.put("A",startValue2);
        Map<String,Integer> startValue3 = new HashMap<>(2);
        startValue3.put("A",3);
        startValue3.put(END,5);
        grapth.put("B",startValue3);
        grapth.put(END,null);
        return grapth;
    }
}

  • 贪婪算法

动态规划

学习点

  1. 学习动态规划,这是一种解决棘手问题的方法,它将问题分成小问题,并先着手解决这些小问题

  2. 学习如何设计问题的动态规划解决方案

工作原理

  • 先解决子问题,再逐渐解决大问题

课后答案
9.1 假设你还可偷另外一件商品——MP3播放器,它重1磅,价值1000美元。你要偷吗?

不要,因为重1磅的吉他价值1500磅,所有偷Mp3播放器在本题中目前没有意义

9.2 假设你要去野营。你有一个容量为6磅的背包,需要决定该携带下面的哪些东西。其中每样东西都有相应的价值,价值越大意味着越重要:
 水(重3磅,价值10)
 书(重1磅,价值3)
 食物(重2磅,价值9)
 夹克(重2磅,价值5)
 相机(重1磅,价值6)
请问携带哪些东西时价值最高?

1 2 3 4 5 6
10(水) 10(水) 10(水) 10(水)
3(书) 3(书) 10(水) 13(水、书) 13(水、书) 13(水、书
食物 3(书) 9(食物) 11(书、食物) 13(水、书) 19(水、食物) 22(水、书、食物)
夹克 3(书) 9(食物) 11(书、食物) 14(食物、夹克) 19(水、食物) 22(水、书、食物)
相机 6(相机) 9(书、相机) 15(食物、相机) 17(书、食物、相机) 20(食物、夹克、相机) 25(水、食物、相机)

9.3 请绘制并填充用来计算blue和clues最长公共子串的网格
最长公共子串:

b l u e
c 0 0 0 0
l 0 1 0 0
u 0 0 2 0
e 0 0 0 3
s 0 0 0 0

最长公共子序列:

b l u e
c 0 0 0 0
l 0 1 1 1
u 0 1 2 3
e 0 1 2 3
s 0 1 2 3

背包问题启示

  • 每种动态规划解决方案都涉及网格。
  • 单元格中的值通常就是你要优化的值。在前面的背包问题中,单元格的值为商品的价值。
  • 每个单元格都是一个子问题,因此你应考虑如何将问题分成子问题,这有助于你找出网格的坐标轴。

小结

  • 需要在给定约束条件下优化某种指标时,动态规划很有用。
  • 问题可分解为离散子问题时,可使用动态规划来解决。
  • 每种动态规划解决方案都涉及网格。
  • 单元格中的值通常就是你要优化的值。
  • 每个单元格都是一个子问题,因此你需要考虑如何将问题分解为子问题。
  • 没有放之四海皆准的计算动态规划解决方案的公式
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

算法图解笔记(附PDF下载地址) 的相关文章

  • FS技术总结

    技术总结 1 单机FIO测试 1 1 配置FS环境 1 2 配置 Linux NVMe over Fabrics 主机 1 3 FIO通过配置文件运行 1 4 双机 双fio测试 1 5 fio测试 2 优化代码 2 1 程序运行细节 3

随机推荐

  • 【JavaEE】多线程CAS中的aba问题是什么?

    博主简介 想进大厂的打工人 博主主页 xyk 所属专栏 JavaEE初阶 什么是CAS问题 CAS 全称Compare and swap 字面意思 比较并交换 CAS中的aba问题是什么 请看本文讲解 目录 文章目录 一 CAS是什么 二
  • Qt 串口调试助手16进制收发显示

    就不废话了 直接贴源码 如果你看懂我的源码的画 我认为90 的概率能解决你16进制显示问题 注意 注意 注意 qt低版本可能不提供arr hex 这个函数 源码 QString str ui gt lineEdit gt text 从QLi
  • C++函数中返回引用和返回值的区别

    一 主要讨论下面两个函数的区别 int at return m data int at return m data 上面两个函数 第一个返回值是int的引用int 第二个返回值是int 二者的区别是什么呢 我们先用一个语句 const in
  • ElasticSearch 单机、集群安装

    文章目录 ElasticSearch 基本概念 安装启动 集群配置 快速启动一个集群节点实例 集群的状态 ElasticSearch 基本概念 索引 含有相同属性的文档集合 类型 索引可以定义一个或多个类型 文档必须属于一个类型 文档 文档
  • vue自定义tree树组件

    组件内容
  • java类和对象及python中的类似实现

    一 java类和对象 首先 我们简单说一下类和对象的理解 所有男的这相当于一个 类 而某个具体的人就是一个 对象 类 当做对象的模板 对象 根据类创建 在java中 使用关键词new创建新对象 java中定义一个类 public class
  • Node常用命令

    1 Node 使用淘宝镜像 npm install g mirror config china registry http registry npm taobao org 查询当前镜像 npm config get registry npm
  • [CVPR-21] Robust and Accurate Object Detection via Adversarial Learning

    代码 https github com google automl tree master efficientdet Det AdvProp md 目录 摘要 引言 方法 AdvProp Det AdvProp 实验 质量实验 消融实验 摘
  • Python每日一练第5天——将一组数尽可能均匀地分成两堆,使两个堆中的数的和尽可能相等

    每日一练 做题 麦克叔叔去世了 他在遗嘱中给他的两个孙子阿贝和鲍勃留下了一堆珍贵的口袋妖怪卡片 遗嘱中唯一的方向是 尽可能均匀地分配纸牌的价值 作为Mike遗嘱的执行人 你已经为每一张口袋妖怪卡片定价 以获得准确的货币价值 你要决定如何将口
  • 【软件工程】之结构化设计

    结构化设计思考题如下 一 软件结构图 1 主要元素 2 形态特征指标 3 优化准则 1 模块独立性准则 2 软件结构的形态特征准则 3 模块的大小准则 4 模块控制域与作用域的准则 5 模块的接口准则 二 数据流模型 1 类型 1 变换流
  • QT中的信号与槽连接关系

    对于QT的信号与槽 进行一个信号连接两个槽 QT中connect的连接类型 AutoConnection在单线程中 按照默认的循序去触发相应的槽函数 DirectConnection在单线程中 对应的slot函数会被立刻调用 优先级高于主线
  • Angular开发(十四)-利用angular的http转发、即代理http 请求,处理项目中请求跨域的问题

    虽然angular的http请求中提供了jsonp处理跨域问题 但是不常用 我们web服务器端可能会选择别的方式处理 web服务器端使用nginx进行反向代理处理 使用nodejs中node http proxy解决本地开发ajax跨域问题
  • Com Surrogate

    昨晚 偶然间发现自己只要打开AVI格式的视频 电脑右下角的任务栏就会跳出一个小图标 并且COM Surrogate停止工作 问题事件名称 BEX 应用程序名 DllHost exe 应用程序版本 6 1 7600 16385 应用程序时间戳
  • How do I integrate my application with CXF

    http cxf apache org docs how do i integrate my application with cxf html Transports CXF支持 HTTP JMS Local等传输方式 Bindings C
  • Java文字转语音

    注意 只能在windows上使用 import com jacob activeX ActiveXComponent import com jacob com Dispatch import com jacob com Variant 文字
  • mongodb二进制操作

    https mongodb github io mongo cxx driver api legacy 1 0 4 bsonmisc 8h source html https github com waitman mongo cxx dri
  • 搜索引擎工作原理

    点击上方关注 前端技术江湖 一起学习 天天进步 作者 君额上似可跑马 https segmentfault com a 1190000019830311 搜索引擎的工作过程大体可以分为三个阶段 1 对网页进行抓取建库 搜索引擎蜘蛛通过抓取页
  • GDCM: 图像片段分割器(gdcm::ImageFragmentSplitter)的测试程序

    GDCM 图像片段分割器 gdcm ImageFragmentSplitter 的测试程序 include
  • Scala学习笔记(三)——类和对象

    3 1 类 字段和方法 类和字段与java类似 方法推荐尽量避免使用返回语句 尤其是多条返回语句 代之可以把每个方法当作是创建返回值的表达式 如下 3 2 分号推断 除非以下情况的一种成立 否则行尾被认为有分号 1 由一个不能合法作为语句结
  • 算法图解笔记(附PDF下载地址)

    算法图解笔记 分治策略 散列函数 广度优先搜索 狄克斯特拉算法 动态规划 算法图解 pdf版 链接 https pan baidu com s 1FJvija2NNmhOSpd7D3yE g 提取码 bwcm 分治策略 分治策略 分而治之