随笔分类 - 经典算法
摘要:一. 带定时器和锁的LRU缓存 #include <iostream> #include <unordered_map> #include <chrono> #include <mutex> #include <thread> using namespace std; class LRUCache
阅读全文
摘要:一. 使用两个哈希实现 一个哈希进行直接索引,另一个哈希根据访问频率索引双向链表 /* 定义Node类 双链表节点,包含键、值、前驱、后继 定义LFUCache 类 变量 min_freq:当前最小频率层次 capacity:容量 key_to_node:根据键值索引节点的哈希 freq_to_du
阅读全文
摘要:一. 概述 树状数组是一种支持数组的单点修改,以及求前缀和(区间求和)的一种简单数据结构,作为线段树的下位替代 简单来说,树状数组就是利用lowbit(二进制化最后一位表示的值)的性质,把n个节点串起来,隐式地构造一棵树 每个节点x的父亲是x+lowbit(x),当前x节点左边最大的节点是x-low
阅读全文
摘要:###一. 概述 线段树(Segment Tree)是一种用于**处理区间查询和更新的数据结构** 常用于解决一维区间相关的问题,如区间最值、区间和、区间乘积等 线段树的基本思想是将区间划分为一些小的子区间,并在每个子区间上维护一些信息 例如该区间的最值、和、乘积等,通过将大区间不断划分为小区间,直
阅读全文
摘要:###一. 概述 Dijkstra算法是求一个顶点到其余各顶点的最短路径算法- 迪杰斯特拉算法主要特点是从起始点开始,采用贪心算法的策略 每次遍历到始点距离最近且未访问过的顶点的邻接节点,直到扩展到终点为止 ###二. 算法流程 1. 建立图的存储结构(邻接矩阵/邻接表) 2. 初始化图 3. 初始
阅读全文
摘要:####1. 跳表介绍 跳表是一种随机化的数据结构,可以被看做二叉树的一个变种,它在性能上和红黑树、AVL树不相上下, 但是跳表的原理非常简单,目前在Redis和LevelDB 中都有用到 跳表的期望空间复杂度为 O(n),跳表的查询,插入和删除操作的期望时间复杂度均为O(logn) 跳表实际为一种
阅读全文
摘要:Trie 是一颗非典型的多叉树模型 每个节点分裂成对应26个字母的子节点,从上往下形成任一单词的前缀 下面来定义一个字典树的类 ####1. 属性 class Trie { private: bool isEnd;//是否为叶子节点 Trie* next[26];//26棵子树 public: //
阅读全文
摘要:###1. 介绍 对一个数量未知的样本,希望只经过一次遍历就完成随机抽样,即时间复杂度O(n) 因为样本数量未知,因此就不能通过random函数直接随机抽样 策略为从前往后遍历,每个样本成为答案的概率为1/i,其中i为样本编号,最终可以使每个样本概率为1/n 容易证明该做法的正确性,假设最终成为答案
阅读全文
摘要:###1. 概述 并查集用来解决图的连通性问题,并查集的方法首先要为每一个点建立集合, 接着写出判断两个点是否属于一个集合的方式,最后不断合并集合 ####**常用模板** ``` int find(int i){ //寻找集合首索引,即集合的唯一标识符 if (parent[i] != i) pa
阅读全文
摘要:###一. 最简单的字符串匹配 >记录两初始指针从前往后移动,匹配成功则一起后移 匹配失败则模板串指针回到首位,被匹配串指针移到上一次上一次初始匹配的下一位置 直至模板串匹配完返回真,或者被匹配串匹配完返回假,时间复杂度为O(mn) > ``` class Solution { public: in
阅读全文
摘要:判断拓扑排序有入度表方式和深度优先(锁路径)无回路方式 其中入度表的能通过栈完成所有无前驱节点访问,也能通过队列广度优先完成访问,本质上只是存储无前驱节点的容器 构建对应拓扑序列序列只能用入度表的方式,按顺序解锁无前驱节点 bool TopologicalSort(Graph G){ stack<i
阅读全文
摘要:###1. 直接插入排序(有序表的扩大) void InsertSort(int *A,int n){ int i,j; for(i=2;i<=n;i++){ //从第二个元素开始遍历n-1次,插入到前面的有序数组中 A[0]=A[i]; //存储待插入元素 for(j=i-1;A[0]<A[j];
阅读全文