石器时代 —— 系统的学习算法


在这里插入图片描述
本文参考 - 知乎

  • 10个数据结构:数组、链表、栈、队列、散列表、二叉树、堆、跳表、图、Trie 树
  • 10个算法:递归、排序、二分查找、搜索、哈希算法、贪心算法、分治算法、回溯算法、动态规划、字符串匹配算法

复杂度

  • 常数阶O(1)
  • 线性阶O(n)
  • 平方阶O(n²)
  • 对数阶O(logn)
  • 线性对数阶O(nlogn)
    在这里插入图片描述

常见算法复杂度

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

常见算法思想

贪心

从问题的某一初始解出发
    while (能朝给定总目标前进一步) 
        do
            选择当前最优解作为可行解的一个解元素;
    由所有解元素组合成问题的一个可行解。

动态规划

  • 流程
    • 问题拆解,找到问题之间的具体联系
    • 状态定义
    • 递推方程推导
    • 实现
  • DP
    • 解动态规划题目其实就是拆解问题,定义状态的过程,严格说来,动态规划并不是一个具体的算法,而是凌驾于算法之上的一种 思想
    • 从局部最优解通过一定的策略推得全局最优解,从子问题的答案一步步推出整个问题的答案,并且利用空间换取时间

120. 三角形最小路径和

参考

class Solution {
public:
    int minimumTotal(vector<vector<int>>& triangle) {
        int N = triangle.size();
        int dp[N][N];
        for (int i = 0; i < N; i++) 
            dp[N-1][i] = triangle[N-1][i];
        for (int i = N - 2; i >= 0; i--) {
            for (int j = 0; j < triangle[i].size(); j++) {
                dp[i][j] = min(dp[i+1][j], dp[i+1][j+1]) + triangle[i][j];
            }
        }
        return dp[0][0];
    }
};

256. 粉刷房子

参考

class Solution {
public:
    int minCost(vector<vector<int>>& costs) {
      int r = 0, b = 0, g = 0;
      for (auto& c : costs) {
        int r0 = min(c[0]+b, c[0]+g);
        int b0 = min(c[1]+r, c[1]+g);
        int g0 = min(c[2]+r, c[2]+b);
        r = r0; b = b0; g = g0;
      }
      return min(r, min(b, g));
    }
};

265. 粉刷房子II

参考

分治策略

  • 对于一个规模为 n 的问题,若该问题可以容易地解决(比如说规模 n 较小)则直接解决,否则将其分解为 k 个规模较小的子问题,这些子问题互相独立且与原问题形式相同,递归地解这些子问题,然后将各子问题的解合并得到原问题的解 T(n)= k T(n/m) + f(n)
    Divide-and-Conquer(P)
    if |P| ≤ n0
        then return(ADHOC(P))
    将P分解为较小的子问题 P1 ,P2 ,...,Pk
        for i←1 to k
            do yi ← Divide-and-Conquer(Pi) △ 递归解决Pi
        T ← MERGE(y1,y2,...,yk) △ 合并子问题
    return(T)
  • 二分查找
  • 归并排序
  • 快速排序
  • 汉诺塔递归
  • 递归和动规

KMP算法

  • 动态规划构图,也可以使用递归和带备忘录的递归
    参考

排序

十大排序算法

ObjectC:参考

Jave:参考

Java:参考2

搜索

拓扑排序

  • 拓扑排序就是根据这些依赖来给出一个做事情,或者是事件的一个顺序
  • BFS/DFS

查找

  • 二分查找

字符串匹配

Boyer-Moore 算

  • 简称 BM 算法
  • 从模式串的尾部开始匹配,且拥有在最坏情况下 O(N) 的时间复杂度。有数据表明,在实践中,比 KMP 算法的实际效能高,可以快大概 3-5 倍。
  • 它是基于以下两个规则让模式串每次向右移动 尽可能大 的距离。
    • 坏字符规则(bad-character shift):当文本串中的某个字符跟模式串的某个字符不匹配时,我们称文本串中的这个失配字符为坏字符,此时模式串需要向右移动,移动的位数 = 坏字符在模式串中的位置 - 坏字符在模式串中最右出现的位置。此外,如果"坏字符"不包含在模式串之中,则最右出现位置为 -1。坏字符针对的是文本串。
    • 好后缀规则(good-suffix shift):当字符失配时,后移位数 = 好后缀在模式串中的位置 - 好后缀在模式串上一次出现的位置,且如果好后缀在模式串中没有再次出现,则为 -1。好后缀针对的是模式串。

参考

KMP算法

  • Knuth-Morris-Pratt 字符串查找算法,简称为 KMP算法,常用于在一个文本串 S 内查找一个模式串 P 的出现位置。

参考

Brute-Force算法

  • BF算法
  • 流程:
    • 对于给定的主串 S 与子串 P ,主串 S 的长度为 N,子串 T 的长度为 M ;
    • 首先,将 S[1] 和 T[1] 进行比较;
    • 若相等,则再比较 S[2] 和 T[2] ,一直到 T[M] 为止;
    • 若 S[1] 和 T[1] 不等,则 T 向右移动一个字符的位置,再依次进行比较;
  • 缺点:BF算法 在主串和字串匹配失败时,主串进行的回溯操作会影响效率,回溯之后,主串与字串有些部分比较是没有必要的。这种简单的丢弃前面的匹配信息是 BF算法 之所以效率低效的一个重要因素。

参考

数据

线性表

散列表

  • 哈希洪水攻击(Hash-Flooding Attack)?
  • 布隆过滤(Bloom Filter):现在有一个非常庞大的数据,假设全是 int 类型。现在我给你一个数,你需要告诉我它是否存在其中(尽量高效)。
    • 它主要就是用于解决判断一个元素是否在一个集合中,但它的优势是只需要占用很小的内存空间以及有着高效的查询效率。

二叉树

  • 常见题目 链接
  • 二叉搜索树 BST
  • 平衡二叉树 AVL
    参考

B树

  • 对BST,红黑树,B树,B+树的白话:参考
  • B-树:参考

2-3树 / 2-3-4树

2-3树
2-3-4树

字典树(Trie树)

  • Trie 树,也叫“字典树”。顾名思义,它是一个树形结构。它是一种专门处理字符串匹配的数据结构,用来解决在一组字符串集合中快速查找某个字符串的问题。
  • Trie 树也称前缀树(因为某节点的后代存在共同的前缀,比如pan是panda的前缀)
  • 它的key都为字符串,能做到高效查询和插入,时间复杂度为O(k),k为字符串长度,缺点是如果大量字符串没有共同前缀时很耗内存
  • 核心思想就是通过最大限度地减少无谓的字符串比较,使得查询高效率,即「用空间换时间」,再利用共同前缀来提高查询效率
    在这里插入图片描述
  • 特点
    • 根节点不包含字符,除根节点外每一个节点都只包含一个字符
    • 从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串
    • 每个节点的所有子节点包含的字符都不相同

参考

  • 字典树的两大基本用法:
    • 确认一个单词是否在字典中存在
    • 确认字典中是否含有某前缀的单词
      • 求得字典中含有某前缀的所有单词
      • 计算字典中含有某前缀的单词的个数
      • 计算字典中含有某前缀的单词的出现频率

参考2

拓扑排序

参考

图论基础与图存储结构

参考

图的DFS/BFS

图的最短路径

参考

最小生成树

参考

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值