中级算法
文章平均质量分 94
ACM、蓝桥杯中级算法
优惠券已抵扣
余额抵扣
还需支付
¥9.90
¥99.00
购买须知?
本专栏为图文内容,最终完结不会低于15篇文章。
订阅专栏,享有专栏所有文章阅读权限。
本专栏为虚拟商品,基于网络商品和虚拟商品的性质和特征,专栏一经购买无正当理由不予退款,不支持升级,敬请谅解。
数学家是我理想
博客:https://wmathor.com
展开
-
TRIE(2)
实现TRIE结构 第一种方法是用一个二维数组来存储:int trie[MAX_NODE][CHARSET];int k; 其中MAX_NODE是trie中最大能存储的节点数目,CHARSET是字符集的大小,k是当前trie中包含有多少个节点。Trie[i][j]的值是0表示trie树中i号节点,并没有一条连出去的边,满足边上的字符标识是字符集中第j个字符(从0开始);trie[i...原创 2018-08-21 08:42:49 · 294 阅读 · 0 评论 -
TRIE(3)
例2 题目链接:hihoCoder1107 搜索引擎现在一般都有关键词提示或者说是补全功能。就是当你在搜索框里输入一个关键词s时,搜索引擎会自动提示你一些频率比较高,同时前缀是s的关键词 这道题的大意就是给定你N个高频的查询字符串。然后题目定义如果一个字符串s满足,有不少于5个高频字符串是以s为前缀的,那么我们就称s是“合适的前缀”。同时如果一个“合适的前缀”s,删掉s的最后一个字符之...原创 2018-08-21 08:43:07 · 245 阅读 · 0 评论 -
TRIE(4)
例3 题目链接:hihoCoder1289 这道题的大意是我们有一个网站,然后要配置规则,决定哪些IP能访问,哪些IP不能。这些规则大概长这个样子:allow 1.2.3.4/30deny 1.1.1.1allow 127.0.0.1allow 123.234.12.23/3deny 0.0.0.0/0 allow是允许访问,deny是不允许访问。后面这个1.2.3.4...原创 2018-08-21 08:43:22 · 207 阅读 · 0 评论 -
堆及其相关应用
什么是堆? 提到堆就不得不说到二叉树这个结构,堆就是一颗完全二叉树,什么叫完全二叉树,用一句话来概括就是:设二叉树的深度为h,除第h层外,其它各层的结点数都达到最大个数,第h层所有的结点都连续集中在最左边,这就是完全二叉树,举几个例子: 堆分两种,一种叫大根堆,一种叫小根堆。大根堆就是在堆结构中,任意一棵子树的根节点一定是最大值,举个例子: 看上图最左边的那颗树,他的子树有64...原创 2018-08-12 10:09:16 · 284 阅读 · 0 评论 -
位与进制
位运算简介 这里我假设读者有二进制的思维,知道(3)~10~=(011)~2~将十进制转换为二进制的方法 - &(与)、|(或)、^(异或)、~(非/取反) - >>和<<运算符将二进制位进行右移或者左移操作 - >>>运算符将用0填充高位;>>运算符用符号位填充高位,没有<<<运算符 - 对于int型,1...原创 2018-08-12 10:10:14 · 359 阅读 · 0 评论 -
并查集(Union Find)
没想到有一天我也能搞懂并查集,orz……实际上本文算是《Algorithms》一书的读后感1.并查集概述 并查集的数学模型是一组不相交的动态集合S={A,B,…},它支持以下运算: 1. union(A,B):将集合A和集合B合并 2. find(x):找出包含元素x的集合 3. connected(A,B):返回A和B是否连通我们看一张图来具体说明 开始的情况是对...翻译 2018-08-12 10:10:40 · 309 阅读 · 0 评论 -
二分查找与二分答案(1)
我们在写程序的时候,经常会遇到这样一类问题:在一个数组中查找一个数是不是存在。比如在下图的数组中,查找8是不是存在: 如果不要求效率,我们最一般的查找方法就是顺序查找,依次查看a[0], a[1], …, a[n-1],检查是不是等于8。这样对于长度为n的数组,平均查找长度是n/2 如果数组是有序的,比如是递增的,就像上图[1, 2, 3, 4, 5, 7, 8, 10, 11, 1...原创 2018-08-13 19:11:00 · 1703 阅读 · 0 评论 -
二分查找与二分答案(2)
溢出风险 我们首先回顾一下上一次二分算法的代码#include<iostream>using namespace std;int n,x,a[1000000];int binary_search(int a[],int n,int x){ int l = 0; int r = n - 1; int ans = -1; while(l ...原创 2018-08-13 19:11:18 · 389 阅读 · 0 评论 -
二分查找与二分答案(3)
例1 关于从长方形的巧克力中切出正方形的小巧克力,可以看下面的示意图: 上图是一块5x6的巧克力分别切出1x1、2x2和3x3的示意图。切成1x1一共可以切出30块,切成2x2可以切出6块。四个1是一块,四个2是一块,以此类推。切成3x3一共可以切出2块。用公式来说的话,一块HxW的巧克力,如果要切出边长是x的正方形,一共可以切出⌊H/x]*[W/x]块正方形的巧克力 现在题目的要求是...原创 2018-08-13 19:11:38 · 359 阅读 · 0 评论 -
搜索(1)
图的存储 在讨论图的遍历问题之前,我们先来讨论一下图的存储问题,也就是我们在写程序的时候如何保存、表示一个图。首先我们会用连续的整数编号来表示点集。比如1号顶点、2号顶点…… 其次,我们有两种方法表示边集。一种叫做邻接矩阵表示法,另一种叫邻接表表示法 邻接矩阵是说我们用一个二维矩阵A来表示边集。A~ij~=0表示顶点i和顶点j之间不存在边,A~ij~=1表示顶点i和顶点j之间存在边。例...原创 2018-08-13 19:12:04 · 378 阅读 · 0 评论 -
搜索(2)
上一节我们以图的遍历为例讲了深度优先搜索算法和实现程序。上一节中的深度优先算法可以算是基本款,很多深度优先搜索的题目就是在这个基本款的程序上进行修改DFS 加强版DFS首先增加或者说变化的一点是顶点颜色。我们在基本款代码里使用visited数组来区分顶点,也就是visited[x]==true表示x顶点已经访问过,visited[x]==false表示还没访问过x顶点。加强版中使用”...原创 2018-08-13 19:27:22 · 201 阅读 · 0 评论 -
搜索(3)
例2 八皇后问题 八皇后问题用一句话来描述,就是:找到所有在8*8的国际象棋棋盘上放置8枚皇后棋子并且满足任意两枚皇后不会互相攻击的方案 我们先来看一下国际象棋的棋盘: 棋盘是由8×8等于64个方格组成。棋子是放在方格中的,而不是像中国象棋或者围棋那样放在横线和纵线的交叉点上。上图中的棋子就是皇后,如果有其他棋子与皇后在同一行、同一列或者同一对角线(包含两个方向的对角线)上,都会被皇...原创 2018-08-13 19:27:34 · 270 阅读 · 0 评论 -
搜索(4)
用DFS在2D地图上找连通分量的问题例4 蓝桥杯——全球变暖 题目大意是有一张NxN像素的照片,图片中”#”代表陆地,”.”代表海洋。”上下左右”4连通连成一片的陆地组成一座岛屿。如下图题目里的照片中,有两座岛屿,分别用红框标记出来: 然后题目说由于全球变暖,海平面上升,预计岛屿边缘一个像素范围内的陆地都会被淹没。所谓岛屿边缘像素就是与海洋相邻的像素,也就是上下左右有海洋...原创 2018-08-14 10:31:14 · 294 阅读 · 0 评论 -
搜索(5)
深度优先搜索一般是递归实现的,搜索过程中总是优先遍历当前节点的子节点。从这一节开始,我们将学习广(宽)度优先搜索 这个GIF图中,节点被染成绿色的顺序表示在宽度优先搜索过程中节点被访问的顺序。可以看到从根节点开始访问,每当一层的节点都被访问过后,下一层的节点才会开始被访问。接下来我们对整个过程进行更详细的分解: 1. 在搜索的第一步,访问根节点,即是节点1。由于该层只有节点1这一个节点...原创 2018-08-14 10:32:09 · 410 阅读 · 0 评论 -
搜索(6)
例1 蓝桥杯——穿越雷区 题目大意是在一个nxn的方阵地图上,每一个方格都标记+号或者-号,要从A点到B点。题目要求移动路线要+-交替,问怎么移动从A到B才是最短路径? 同样的,这道题也是一道2D网格图上的最短路径问题。我们仍然采用相同的思路来解决它 相较于上一讲的问题,本题主要有以下两个个不同之处: - 起始点不在固定,而是通过字符地图给出。在这道题目中起点为A,终点为B -...原创 2018-08-14 10:32:26 · 491 阅读 · 0 评论 -
搜索(7)
例3 蓝桥杯——迷宫与陷阱 这道题迷宫中多了一些花样。一是迷宫中有陷阱,由X表示。除非处于无敌状态,否则不能经过陷阱。二是有些位置到达后会自动获得无敌状态,持续K步 我们可以看一下样例给的两个数据: 这两个地图其实是一样的。区别在于左边的数据无敌状态持续3秒,可以拿到无敌之后经过右上角的陷阱到达终点。右边的数据无敌只持续1秒,所以拿到无敌来不及经过右上角的陷阱无敌就消失了,所以...原创 2018-08-14 10:33:48 · 312 阅读 · 0 评论 -
搜索(8)
A*算法 很多人应该都玩过类似下面这样的拼图游戏(华容道): 为了简化题目,我们只使用3x3的规模,并且按照从上到下,从左至右,将每块拼图标记为正确位置的编号 上图中左边是初始的状态,而我们的目的是利用空格(灰色区域)作为辅助,将初始状态转变为右图的状态。每一次移动,我们可以将空格与它周围的方块交换位置 根据描述,能够看出这个问题仍然是一个通过宽度优先搜索来解决的最短路径问...原创 2018-08-14 10:34:09 · 594 阅读 · 0 评论 -
KMP(1)
字符串匹配问题 首先我们先把问题明确一下,给定两个字符串P[1..P.len]和S[1..S.len],找出P在S中第一次出现的位置L,即最小的L满足P[1..len]=S[L..L+len-1]。例如”HA”在”WAHAHA”中第一次出现的位置是3(这一节约定下标都是从1开始)暴力算法 从小到大枚举L,然后判断P[1..len]=S[L..L+len-1]的条件是不是满足;不满足...原创 2018-08-14 10:34:54 · 254 阅读 · 0 评论 -
KMP(2)
求next数组(暴力版本)Next[0] = -1Next[1] = 0For i = 2...P.len Next[i] = 0; For j = i - 1...1 If P[1...j] == P[i - j + 1...i]//P[1...j]是P[1...i]的后缀 Next[i] = j Bre...原创 2018-08-14 10:35:15 · 171 阅读 · 0 评论 -
KMP(3)
例2 题目链接:HDOJ1711 这个题目的大意就是给你一个整数数组A=[A1, A2, … AN]和一个整数数组B=[B1, B2, … BM],让你找到一个位置K使得从A[K]开始的M个整数与[B1, B2, … BM]相等。如果没有满足条件的位置K就输出-1 这其实就是一个整数版的KMP。我们之前讲KMP的背景都是字符串匹配,其实也可以拿来做数组序列匹配。只要把整数相等对应成字符...原创 2018-08-14 10:35:32 · 249 阅读 · 0 评论 -
KMP(4)
例6 题目链接:POJ2752 这道题目的大意是给定一个字符串S,让找出所有既是S前缀又是S后缀的字符串。然后从小到大输出它们的长度 比如S=ababcababababcabab,既是前缀又是后缀的有ab, abab, ababcabab和S本身。所以输出的是2 4 9 18。再比如S=aaaaa,既是前缀又是后缀的有a, aa, aaa, aaaa和S本身。所以输出的是1 2 3 4...原创 2018-08-14 10:36:07 · 255 阅读 · 0 评论 -
TRIE(1)
Trie又被称为前缀树或者字典树。它的基本作用是用来存储一个字符串集合:{W1, W2, W3, … WN},并且可以用来查询一个字符串S是不是在集合里 具体来说,Trie一般支持两个操作: 1. Trie.insert(W):第一个操作是插入操作,就是将一个字符串W加入到集合中 2. Trie.search(S):第二个操作是查询操作,就是查询一个字符串S是不是在集合中 由于Tri...原创 2018-08-14 10:36:26 · 380 阅读 · 0 评论 -
枚举+优化(6)——双指针优化2
例3.题目链接:hihoCoder1514 先写一个暴力枚举的伪代码:ans = MAX_INTFor i = 1...M{ For j = 1...N { For k = 1...L { s = |Ai - Bj| + |Bj - Ck| + |Ai - Ck| IF s < ...原创 2018-08-13 19:10:19 · 306 阅读 · 0 评论 -
枚举+优化(7)——前缀和1
例1 给定一个长度为N的数组:A1,A2,…,AN。(N <= 100000,1 <= A[i] <= 100000)。然后有M个询问,每次询问给两个整数L,R问A[L]~A[R]的和是多少。(M <= 100000)。 这道题最直接的做法就是每次询问的时候,用一个循环累加A[L]~A[R]的和,伪代码如下:Ask(L,R)Sum = 0For i = L...原创 2018-08-13 19:10:33 · 667 阅读 · 0 评论 -
枚举+优化(8)——前缀和2
例3.题目链接:hihoCoder1534 这道题要注意一下数据范围。首先N小于等于10万。其次Ai,也就是数组中每个数的值,是在负100万到正100万之间。假如这里Ai都是正整数的话,那么总共的划分方法不会太多,因为随着p增大,第一段的和S1是不断增大的。 但是因为这里Ai有可能是0,也有可能是负数,所以划分方法可能非常多。例如有可能数据是10万个Ai全都是0。这样随便一个划分都是满足条...原创 2018-08-13 19:10:45 · 313 阅读 · 0 评论 -
枚举+优化(1)——枚举
十位平方数 由0~9这10个数字不重复、不遗漏,可以组成很多10位数字。这其中也有很多恰好是平方数。 比如:1026753849,就是其中一个最小的平方数。 请你找出其中最大的一个平方数是多少?思路1枚举答案X [9876853210,1026753849](从最大的数枚举到最小的数)判断是不是恰好0-9十个数字判断是不是完全平方数 1) 令Y = int(sqrt(x...原创 2018-08-12 10:11:16 · 633 阅读 · 0 评论 -
枚举+优化(2)——哈希表优化
问题:查找一个元素是不是存在?unordered_set unordered_set可以想象成一个集合,它提供了三个函数让我们增删查,下面三个函数的时间复杂度都是O(1) 1. unordered_set::insert 2. unordered_set::find 3. unordered_set::erase#include <unordered_set>...原创 2018-08-12 10:11:34 · 290 阅读 · 0 评论 -
枚举+优化(3)——哈希表优化实例1
例1.//两重循环枚举,时间复杂度O(N^2)#include <bits/stdc++.h>using namespace std;int n,k,a[100000];set<pair<int,int>> myset;int main(){ cin >> n >> k; for(int i = 0...原创 2018-08-12 10:11:49 · 413 阅读 · 0 评论 -
枚举+优化(4)——哈希表优化实例2
例3.四平方和思路1:枚举abcd,判断a^2^+b^2^+c^2^+d^2^是否等于N 分析规模 a:0 ~ sqrt(500000 / 4) b:0 ~ sqrt(500000 / 3) c:0 ~ sqrt(500000 / 2) d:0 ~ sqrt(500000) 范围大约是1000 ~ 2000,总枚举量10^12^,经验:1秒=10^8^思路2:枚举...原创 2018-08-12 10:12:02 · 392 阅读 · 0 评论 -
枚举+优化(5)——双指针优化1
有时候我们要对一个数组进行i和j两个下标的双重循环枚举for(int i = 0;i < n;i++){ for(int j = i + 1;j < n;j++) { ... }} 从上面的代码我们能看出时间复杂度是O(N^2^)双指针优化 在某些情况下,根据题目要求,j下标并不需要从i+1重新往后枚举一遍,而是跟...原创 2018-08-12 10:23:11 · 472 阅读 · 0 评论 -
一致性哈希算法
工程设计中常用服务器集群来设计和实现数据缓存,以下是常见的策略:无论是添加、查询还是删除数据,都先将数据的id通过哈希函数转换成一个哈希值,记为key如果目前机器有N台,则计算key%N值,这个值就是该数据所属的的机器编号,无论是添加、删除还是查询操作,都只在这台机器上进行请分析这种缓存策略可能带来的问题,并提出改进的方案普通Hash算法缓存策略的潜在问题是如果增加或删除机器时(N变...原创 2019-09-30 09:14:05 · 379 阅读 · 0 评论 -
布隆过滤器
布隆过滤器概述布隆过滤器解决这样一个问题,假设有一个搜索引擎公司,在他公司的服务器上,有100亿条URL黑名单,当你搜索某个URL的时候,服务器就会检测这些URL在不在黑名单,如果在,就不显示,如果不在,就显示首先算一下这个100亿的URL占多大存储空间,假设一个URL是64字节,算下来总共大概640GB要求:该系统允许有万分之一以下的失误率使用的额外空间不能超过30GB哈希函数...原创 2019-09-30 09:14:36 · 525 阅读 · 1 评论