![](https://img-blog.csdnimg.cn/20201014180756919.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
算法
文章平均质量分 60
evil心安
这个作者很懒,什么都没留下…
展开
-
算法:在O(1)时间删除链表结点(脑筋急转弯)
思路由于并不知道当前结点的前驱结点,故无法使用传统的方法来删除结点。因此这里将下一个结点的值赋给当前结点,并删除下一个结点。这样在效果就相当于删除了当前结点。题目描述给定单向链表的一个节点指针,定义一个函数在O(1)时间删除该结点。假设链表一定存在,并且该节点一定不是尾节点。代码/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; *原创 2021-07-10 08:23:46 · 67 阅读 · 0 评论 -
算法:剪绳子(数学知识)
思路将绳子分为n段n=n1+n2+...+nan = n_1 + n_2 + ... + n_an=n1+n2+...+na等价于求乘积最大max(n1∗n2∗n3....∗na)max(n_1*n_2*n_3....*n_a)max(n1∗n2∗n3....∗na)数学推导将绳子 以相等的长度等分为多段 ,得到的乘积最大。经过复杂的数学推导可以得出3比2更大,因此要尽可能的多分3出来。当n%3==2时说明分完3之后还余一个2。当n%3==1时说明分完3之后还余两个2。题目原创 2021-07-09 20:38:47 · 484 阅读 · 0 评论 -
(c语言易懂版)算法:第k个最长递增子序列
某个整数序列中,去掉0个以上的数字后,剩余的部分就是原序列的子序列。例如,{7,4,9}、{10,4}、{10,9}等是{10,7,4,9}的子序列。而序列{10, 4, 7}具有不同于原序列的排列顺序,因而不属于{10,7,4,9}的子序列。严格递增的子序列称为递增子序列。序列的递增子序列中,最长的序列称为最大递增子序列(LIS)。例如:{5,20,21,22,8,9,10}的最大递增子序列是{5,8,9,10}。(不唯一)给出以不同数字组成(无重复数字)的序列时,请编写程序,计算此序列的LIS中按照字原创 2021-06-22 10:41:29 · 1364 阅读 · 2 评论 -
算法:雷达设备(贪心)
贪心策略将所有区间按右端点排序扫描每个线段如果上一个点(右端点)不在区间中,则选右端点。如果上一个点(右端点)在区间中,则跳过。题目描述假设海岸是一条无限长的直线,陆地位于海岸的一侧,海洋位于另外一侧。每个小岛都位于海洋一侧的某个点上。雷达装置均位于海岸线上,且雷达的监测范围为 d,当小岛与某雷达的距离不超过 d 时,该小岛可以被雷达覆盖。我们使用笛卡尔坐标系,定义海岸线为 x 轴,海的一侧在 x 轴上方,陆地一侧在 x 轴下方。现在给出每个小岛的具体坐标以及雷达的检测范围,请原创 2021-03-12 10:27:21 · 219 阅读 · 0 评论 -
算法:树的直径
思路第一步:从任意一点出发,找到与这一点距离最远的点。第二步:从最远的一点出发,找到与这点距离最远的点,则这两点之间的距离就是树的直径。问题描述很久以前,T王国空前繁荣。为了更好地管理国家,王国修建了大量的快速路,用于连接首都和王国内的各大城市。为节省经费,T国的大臣们经过思考,制定了一套优秀的修建方案,使得任何一个大城市都能从首都直接或者通过其他大城市间接到达。同时,如果不重复经过大城市,从首都到达每个大城市的方案都是唯一的。J是T国重要大臣,他巡查于各大城市之间,体察民情。所以,从一个原创 2021-02-19 10:56:35 · 327 阅读 · 0 评论 -
算法:最小生成树(prime,kruskal,floyd)
最小生成树Floyd算法O(n^3)- 动态规划思路f[i, j, k] 表示从i走到j的路径上除i和j点外只经过1到k的点的所有路径的最短距离。那么f[i, j, k] = min(f[i, j, k - 1], f[i, k, k - 1] + f[k, j, k - 1])读入邻接矩阵,每次通过动态规划转换成从i到j的最短距离矩阵在下面代码中,判断从a到b是否是无穷大距离时,需要进行if(t > INF/2)判断,而非是if(t == INF)判断,原因是INF是一个确定的值,并非真原创 2021-02-17 18:16:02 · 987 阅读 · 0 评论 -
算法:二分图的最大匹配(匈牙利算法)
匈牙利算法有点像挖墙脚这里的男孩子指的是左半部,女孩子指的是右半部。如果你想找的妹子已经有了男朋友,你就去问问她男朋友,你有没有备胎,把这个让给我好吧因为你要去问的都是男孩子,所以存边的时候,都是由男孩子指向女孩子。问题描述给定一个二分图,其中左半部包含n1个点(编号1n1),右半部包含n2个点(编号1n2),二分图共包含m条边。数据保证任意一条边的两个端点都不可能在同一部分中。请你求出二分图的最大匹配数。二分图的匹配:给定一个二分图G,在G的一个子图M中,M的边集{E}中的任意两条原创 2021-02-16 18:36:31 · 117 阅读 · 0 评论 -
算法:合并果子(优先队列)
思路每次将最小的两堆合并,然后将合并后的堆加入队列。循环往复n-1次就可以将n堆合并为一堆。需要注意的是优先队列的语法priority_queue<Type, Container, Functional>Type 为数据类型, Container 为容器类型, Functional就是比较的方式。//升序队列priority_queue <int,vector<int>,greater<int> > heap;//降序队列priority_qu原创 2021-02-14 09:39:13 · 278 阅读 · 0 评论 -
算法:糖果传递(数学推导)
思路:由于最后每个小朋友都会获得相同的糖果。因此最后每个小朋友获得糖果的数量应该是糖果总数的平均数。因此假设每个小朋友会给他逆时针位置上的朋友x1个糖果,那么x1位置上的小朋友就会送出x1个糖果接受x2个糖果,请看下图公式推导。最后可以看出最小代价就是x1到n个点距离的最小值,也就是这n个点的中位数。问题描述有n个小朋友坐成一圈,每人有a[i]个糖果。每人只能给左右两人传递糖果。每人每次传递一个糖果代价为1。求使所有人获得均等糖果的最小代价。输入格式第一行输入一个正整数n,表示小朋友的个原创 2021-02-10 08:34:32 · 349 阅读 · 0 评论 -
算法:欧拉函数
欧拉函数欧拉函数的定义:N=p1a1p2a2...pmam N = p_1^{a_1} p_2^{a_2}...p_m^{a_m} N=p1a1p2a2...pmam,则欧拉(N)=N∗p1−1p1∗p2−1p2∗...∗pm−1pm欧拉(N) = N * \frac{p_1-1}{p_1}* \frac{p_2-1}{p_2}*...* \frac{p_m-1}{p_m}欧拉(N)=N∗p1p1−1∗p2p2−1∗...∗pmpm−1意义是与N互质的数的个数。质数p原创 2021-02-09 19:38:38 · 153 阅读 · 0 评论 -
算法:约数,约数个数,约数和,最大公约数(b ? gcd(b, a%b) : a;)
约数计算约数时,只需计算到n\sqrt{n}n就可以,大于n\sqrt{n}n的约数可以通过用n除以小于n\sqrt{n}n的约数得到。并且需要特判一下边界n / i != i。void get_divosors(int n){ vector<int> ans; for(int i = 1; i <= n / i; ++i){ if (n % i == 0) { ans.push_back(i); i原创 2021-02-08 11:11:41 · 563 阅读 · 0 评论 -
算法:质数,质因数,筛质数
质数的判定 —— 试除法(O(sqrt(n))质数在大于1的整数中,如果只包含1和本身这两个约数,就被称为质数,或者叫素数。有3中形式由于sqrt()计算较慢。(不推荐)。bool is_prime(int n){ if (n < 2) return false; for (int i = 2; i <= sqrt(n); ++i) if (n % i == 0) return false; return true;}由于i*i有可能会原创 2021-02-07 21:41:10 · 97 阅读 · 0 评论 -
算法:leecode5675.最接近目标值的子序列和(双向dfs)
思路因为数据范围为40,因此需要用到双向dfs,如果数据范围小于20时就可以直接用dfs进行爆搜。思路是将整个数组分为两段,前面一段用dfs爆搜出全部组合的和并存储到数组中。然后将数组排序,再对后面一段进行爆搜,然后当搜索完最后一个元素后就进行二分查找前面与目标值的差最小的绝对值。问题描述给你一个整数数组 nums 和一个目标值 goal 。你需要从 nums 中选出一个子序列,使子序列元素总和最接近 goal 。也就是说,如果子序列元素和为 sum ,你需要 最小化绝对差 abs(sum - g原创 2021-02-07 16:50:30 · 217 阅读 · 1 评论 -
算法:关押罪犯(二分图判定,染色法)
判断一个图是否是二分图二分图的概念:如果顶点C可以分割为两个互不相交的子集,并且图中每条边(i, j)所关联的两个顶点i和j分别属于这两个不同的顶点集,则称图为一个二分图。奇数环的概念:一个环中边的个数是奇数。二分图当且仅当图中不含奇数环。将图中的每个结点染为1或2两种颜色,如果遇到一条边的两个点的染色是相同的,则说明该图不是一个二分图。应该在主函数中加一个for循环遍历每一个连通块,然后用bfs遍历连通块中的每一个结点,使其染色,然后判断是否矛盾,如果矛盾就返回false。用二分来枚举怒气值,原创 2021-02-07 09:55:31 · 268 阅读 · 0 评论 -
算法:最短路(dijkstra)
思路首先最外层循环n次,代表进行n次迭代确定每个点到起点的最小值,最后输出的终点即为要找的最短路的距离。dist[n] 用于存储每个点到起点的最短距离st[n] 用于在更新最短距离时 判断当前的点的最短距离是否确定 是否需要更新每次迭代过程中都需要找到当前未确定的最短距离的点中距离最短的点。int t=-1; for(int j=1;j<=n;j++){ if(!st[j]&&(t==-1||dist[t]>dist[j])原创 2021-02-06 16:45:41 · 166 阅读 · 0 评论 -
算法:聪明的质监员(二分,前缀和)
思路由题意可以知道当不断提高w的值时,满足wj>ww_j > wwj>w的值会越来越少。因此所得的Y会越来越小,所以当提高w,Y就会减少,而题目要求出S−YS-YS−Y的最小值,因此可以用二分的方法通过改变w的值,从而找到S−YS-YS−Y的最小值,也就是Y最接近S的时候W应该取什么值。这里利用前缀和求出当前w值,满足wj>ww_j > wwj>w的数值的前缀和,并计算前i个元素中满足相关条件的值的个数cnt。这样在计算每个区间中的yiy_iyi时就会很快。最原创 2021-02-05 21:25:04 · 76 阅读 · 0 评论 -
算法:有向图的拓扑排序(拓扑排序)
思路:用数组模拟链表,首先如果能用拓扑排序则其一定是有向无环图。所以我们应该先找到其入度为0的点。然后将其入队,并将与此点相连的边全部删去。最后当队尾指针是n-1时说明一共入队n个元素说明此图是有向无环图。存在拓扑排序。注意:h[i]中存储的是元素在e[]中的下标。问题描述给定一个n个点m条边的有向图,点的编号是1到n,图中可能存在重边和自环。请输出任意一个该有向图的拓扑序列,如果拓扑序列不存在,则输出-1。若一个由图中所有点构成的序列A满足:对于图中的每条边(x, y),x在A中都出现在y之原创 2021-02-05 16:50:10 · 2810 阅读 · 0 评论 -
算法:地宫取宝(dp,动态规划)
思路首先给定了一个数n×m地图,每个格子上都有价值不同的物品,每次从左上角出发,然后只能向右或者向下走。每次走到新的格子上,如果当前格子上的价值大于手中全部物品的价值就可以拿走(也可以不拿)。问拿k个物品的方案数?本题用dp的思路来解题,首先用两维表示横坐标和纵坐标。然后用一维来表示当前手上的物品数量。用一维表示当前手中的最大值。当前格子是由左边格子过来的1.1 不取当前格子的物品1.2 取当前格子的物品1.2.1 (需要满足条件当前物品的价值为手中全部价值最大的)那么当前格子的情况就是所有价原创 2021-02-05 09:38:27 · 334 阅读 · 1 评论 -
算法:蚂蚁感冒(蓝桥杯真题,数学知识)
思路由题意当两只蚂蚁相遇时,会掉头朝相反的方向走去,这也可以看作是两个蚂蚁相互穿透。被感冒的蚂蚁穿透之后,这只蚂蚁也会被感染。当第一只蚂蚁向右走,当它右边全部的蚂蚁全部都是向右走的时候,这样这只蚂蚁不会感染到任何一只蚂蚁。而当右边存在任何一只向左走的蚂蚁时,这只蚂蚁也会被感染,同时会将第一只被感染的蚂蚁的左边的所有朝右边走的蚂蚁感染。第一个蚂蚁向右走的情况:1.1 右边向左走的,必然被感染。2.1 右边向右走,必然不会被感染。3.1 左边向左走,必然不会被感染。4.1 左边向右走:4.1.原创 2021-02-04 17:51:01 · 298 阅读 · 0 评论 -
算法:买不到的数目(数学知识)
思路:本题就一个公式当两个数p,q互质时,那么由这两个数凑不成的数最大为(p−1)∗(q−1)−1(p-1)*(q-1) - 1(p−1)∗(q−1)−1问题描述小明开了一家糖果店。他别出心裁:把水果糖包成4颗一包和7颗一包的两种。糖果不能拆包卖。小朋友来买糖的时候,他就用这两种包装来组合。当然有些糖果数目是无法组合出来的,比如要买 10 颗糖。你可以用计算机测试一下,在这种包装情况下,最大不能买到的数量是17。大于17的任何数字都可以用4和7组合出来。本题的要求就是在已知两个包装的数原创 2021-02-04 16:39:22 · 296 阅读 · 0 评论 -
算法:机器人跳跃问题(二分)
思路因为当向上走的时候,它会失去能量故E=E−(H(k+1)−E)E = E - (H(k+1)-E)E=E−(H(k+1)−E),当向下走的时候,会增加能量E=E+(E−H(k+1))E = E + (E - H(k+1))E=E+(E−H(k+1))故可以整理得到E=2∗E−H(k+1)E = 2 * E - H(k+1)E=2∗E−H(k+1)。因此我们可以考虑当E比所有建筑都要高的时候每次E=E+E−H(k+1)E = E + E - H(k+1)E=E+E−H(k+1)都大于等于0因此E只会原创 2021-02-03 22:05:34 · 480 阅读 · 0 评论 -
算法:k倍区间(前缀和)
思路利用前缀和可以快速计算出一个区间的值,然后利用前缀和的取余相同时,相减之后就会等于0,说明如果有k个具有相同余数的区间的话,就能有(k-1)+(k-2)+…+1个区间满足的情况。cnt[0]++是因为如果s[i]取余的值为0时,就相当于从总区间的左端点到i的区间满足情况,所以应该提前加上cnt[0]++。问题描述给定一个长度为 N 的数列,A1,A2,…AN,如果其中一段连续的子序列 Ai,Ai+1,…Aj 之和是 K 的倍数,我们就称这个区间 [i,j] 是 K 倍区间。你能求出数列中总共有多原创 2021-02-02 12:10:57 · 285 阅读 · 0 评论 -
算法:牛异或(前缀和,trie树)
注意trie树的空间复杂度较高因为trie树是一棵二叉树由于每一层都有2i个数,因此一共需要2n+1个空间来存储。另外本题需要id数组来存储下标。也就是最后一层所有存在的数都对应着原数组的下标。因此id数组也需要和trie一样的存储空间。由于异或两次相当于没有异或,因此可以用前缀和来存储。通过端点的异或就可以计算出区间的异或值。问题描述农夫约翰在给他的奶牛们喂食时遇到了一个问题。他共有 N 头奶牛,编号 1∼N。每次喂食前,这 N 头奶牛会按照 1∼N 的顺序站成一排。此外,每头奶牛都被分配原创 2021-02-02 10:51:37 · 205 阅读 · 0 评论 -
算法:背包问题合集(基本囊括了全部背包问题的原始模型)
01背包问题思路每件物体只能使用一次,在固定容量的情况下,可以放入的最大价值。当只使用前i件物品时,可以获得的最大价值一定是大于等于只使用前i-1件物品的。因此当不包含第i件物品时,f[i][j] = f[i-1][j]当包含第i件物品需要满足条件v[i] <= j此时f[i][j] = max(f[i][j], f[i-1][j-v[i]]+w[i])问题描述有 N 件物品和一个容量是 V 的背包。每件物品只能使用一次。第 i 件物品的体积是 vi,价值是 wi。求解将哪些物品装入背包原创 2021-02-01 17:49:09 · 612 阅读 · 0 评论 -
算法:带分数(递归与递推)
思路本题可以枚举1到9的字典序,然后再枚举这三个数每一个数的位数,然后判断是否与系统所给的值相等。问题描述100 可以表示为带分数的形式:100=3+69258714还可以表示为:100=82+3546197注意特征:带分数中,数字 1∼9 分别出现且只出现一次(不包含 0)。类似这样的带分数,100 有 11 种表示法。输入格式一个正整数。输出格式输出输入数字用数码 1∼9 不重复不遗漏地组成带分数表示的全部种数。数据范围1≤N<106输入样例1:100输出样例1:1原创 2021-01-31 21:12:45 · 181 阅读 · 0 评论 -
算法:费解的开关(递推与递归)
本题思路这题类似于我们玩过的一个小游戏。当按下中间按钮时,这个按钮及上下左右四个方向上的灯的开关转换一次。本题要求我们将整个矩阵能否在6步以内点亮。其实这个题的思路很“清奇”因为当我们将第一行的所有操作进行遍历(共有2^5种情况)然后为了将第一行的灯全部点亮,故第二行的操作就能根据第一行灯的状态唯一确定。以此类推就可以确定下面所有的操作。而且只用关心最后一行是否为亮,因为除了最后一行的位置一定是全亮的。问题描述你玩过“拉灯”游戏吗?25盏灯排成一个5x5的方形。每一个灯都有一个开关,游戏者可以改变它原创 2021-01-31 20:32:58 · 544 阅读 · 2 评论 -
算法:加分二叉树(区间DP)
区间dp第一步:循环区间长度第二步:循环左端点,同时判断右端点不能出界。本题的状态表示f[l][r]表示左端点为l,右端点为r的区间中分值最大的值。具体问题情景分析g[l][r]表示当前区间l,r之间最大分值的根节点是谁。用于之后的前序遍历输出。(前序遍历:根-左-右)(中序遍历:左-根-右)当区间长度为1时,根节点没有左右儿子,故它的得分就为它自己本身。当区间长度大于1时,且左端点为根节点时,说明其左儿子为空,故其左儿子得分为1。同理右端点为根节点时,说明其右儿子为空,故其右儿子得分为1。原创 2021-01-31 09:29:10 · 321 阅读 · 0 评论 -
算法:树的重心(树与图的深度优先遍历)
树与图的深度优先遍历本题需要用到用数组模拟链表。用h[i]数组来表示i节点相连的节点有哪些。与哈希中的拉链法的存储方式目的类似。在dfs递归过程中size代表的是在删除一个重心时所有连通块中结点数量最大的数量。ans代表的是已经遍历的重心中,连通块中结点数量最小的数量。问题描述给定一颗树,树中包含n个结点(编号1~n)和n-1条无向边。请你找到树的重心,并输出将重心删除后,剩余各个连通块中点数的最大值。重心定义:重心是指树中的一个结点,如果将这个点删除后,剩余各个连通块中点数的最大值最小,那么原创 2021-01-29 17:57:27 · 189 阅读 · 1 评论 -
算法:八数码(宽搜bfs)
八数码用unordered_map来存储状态对应的字符串和步数。从开始状态出发,检查当前的上下左右是否满足在3×3的格子中,如果满足并且当前的状态没有到达过,那么将此状态添加到队尾,并且将此状态添加到字典中。直到找到终止状态或者队列为空。问题描述在一个3×3的网格中,1~8这8个数字和一个“x”恰好不重不漏地分布在这3×3的网格中。例如:1 2 3x 4 67 5 8在游戏过程中,可以把“x”与其上、下、左、右四个方向之一的数字交换(如果存在)。我们的目的是通过交换,使得网格变为如下排列原创 2021-01-29 12:12:26 · 242 阅读 · 1 评论 -
算法:迷宫问题(宽搜)
宽搜bfs不同于dfs,它不需要用到显式的递归操作,而是将状态存储在队列中,可以用来求权值为1的最短路。每次都将队首的元素取出,然后将可以由这个元素经过一步操作达到的放入队尾。在最短路问题中只要到达过的节点,之后就不会再到达。问题描述给定一个n*m的二维整数数组,用来表示一个迷宫,数组中只包含0或1,其中0表示可以走的路,1表示不可通过的墙壁。最初,有一个人位于左上角(1, 1)处,已知该人每次可以向上、下、左、右任意一个方向移动一个位置。请问,该人从左上角移动至右下角(n, m)处,至少需要移原创 2021-01-28 22:18:41 · 2909 阅读 · 0 评论 -
算法:字符串哈希
字符串哈希两个重要步骤:第一步处理字符串前缀,字符串哈希在求两个字符串是否相等时,有点像求前缀和的思想。p[0] = 1;for(int i = 1; i <= n; ++i){ p[i] = p[i-1] * P; h[i] = h[i-1] * P + str[i];}其中的数组p[i]是预处理p的次方,在后面会用到。注意数组为小写p,而与之相乘的是大写P,经验值为131或者13331。h[i] = h[i-1] * P + str[i]有点像将所有位前移一位,然后原创 2021-01-28 16:44:02 · 464 阅读 · 0 评论 -
算法:模拟散列表(哈希拉链法,开放选址法)
拉链法:用数组h[N]来表示拉链法上对应的链,如果遇到冲突则在对应冲突的位置开一个链,创建链的方式和之前单链表的方式相同。如果要插入一个值:计算当前值在哈希之后的映射位置int k = (x % N + N) % N;之所以要取两次模,是为了处理负数的模将x存储在e[idx]中该链表的下一个位置就是当前冲突位置的链表的头,故ne[idx] = h[k];当前冲突位置链表的头变为了当前的idxh[k] = idx++;开放选址法只需要一个一维数组用来存储。在插入时遇到冲突,按数组顺序向后查原创 2021-01-28 15:35:58 · 310 阅读 · 0 评论 -
算法:火星人(字典序)
next_permutation();输入一个序列可以求出输入序列的下一个序列。发现函数next_permutation()是按照字典序产生排列的,并且是从数组中当前的字典序开始依次增大直至到最大字典序用法与sort一致next_permutation()的实现从后往前找到第一个a[k] < a[k + 1]的位置k在a[k+1]到a[n-1]中找到大于a[k]的最小的数a[t]交换a[k],a[t],交换后可以发现,a[k+1]到a[n-1]是单调递减的将a[k+1]到a[n]逆原创 2021-01-28 10:09:47 · 191 阅读 · 0 评论 -
算法:堆排序(堆)
堆:使用情形:插入一个数求集合当中的最小值删除最小值删除任意一个元素修改任意一个元素用一维数组存储二叉树,左儿子在数组中为根节点在数组中的位置的2倍,右儿子在数组中为根节点在数组中的位置的二倍加一。求当前堆的最小值void down(int u){ int t = u; if(u * 2 <= size && h[u * 2] < h[t]) t = u * 2; if(u * 2 + 1 <= size && h[u * 2 +原创 2021-01-27 16:54:31 · 117 阅读 · 0 评论 -
算法:食物链(并查集)
并查集1.将两个集合合并2.询问两个元素是否在一个集合当中基本原理:每个集合用一棵树来表示。树根的编号就是整个集合的编号。每个节点存储它的父节点,p[x]表示x的父节点。问题1:如何判断树根:if(p[x] == x)问题2:如何求x的集合编号:while(p[x]!=x)x=p[x]问题3:如何合并两个集合:px是x的集合编号,py是y的集合编号。p[x] = y当前问题用d[x]表示到它根节点的距离。由于有三种物种,当x,y在同一集合中时,我们用(d[x] - d[y]) % 3 =原创 2021-01-27 12:03:19 · 581 阅读 · 0 评论 -
算法:合并集合(并查集)
并查集假如有n个集合,要进行对集合的合并或者判断两个数是否在同一个集合中就要用到并查集。int find(x){ if(p[x] != x) p[x] = find(p[x]) return p[x];}我们用p[x]==x来判断当前节点是否为根节点。如果当前节点不是根节点,就进行递推,继续调用find(x),直到找到根节点,之后会进行路径压缩,让根节点的所有子节点都指向根节点。返回值是当前节点的根节点。问题描述一共有n个数,编号是1~n,最开始每个数各自在一个集合中。现在要进行m个操原创 2021-01-27 10:45:26 · 505 阅读 · 0 评论 -
算法:合唱队形(最大上升子序列,线性DP)
最大上升子序列有一个队列,下标从1开始存储。用f[i]代表i点结尾的最大上升子序列的长度。采用递归的思想,从队的最左边开始,由于自身,所以以最左边一点结尾的最大上升子序列为1,故f[1] = 1。以第二点结尾的最大上升子序列当w[1] < w[2]时,f[2] = max(f[2], f[1] + 1)。f[1] + 1 代表的是以1结尾的最大上升子序列加上当前这个点。一般地,f[i] = max(f[i], f[j] + 1) for (int i = 1; i <= n; i原创 2021-01-27 09:56:11 · 370 阅读 · 1 评论 -
算法:trie树
trie树主要用途:快速存储字符串集合的数据结构。问题描述需要两个数组一个用于存储当前位置的下一个结点的坐标,一个用于存储当前位置是否是一个字符串的结尾。维护一个字符串集合,支持两种操作:“I x”向集合中插入一个字符串x;“Q x”询问一个字符串在集合中出现了多少次。共有N个操作,输入的字符串总长度不超过 105,字符串仅包含小写英文字母。输入格式第一行包含整数N,表示操作数。接下来N行,每行包含一个操作指令,指令为”I x”或”Q x”中的一种。输出格式对于每个询问指令”Q x原创 2021-01-22 10:03:20 · 68 阅读 · 0 评论 -
算法:kmp算法
kmp算法定义两个字符数组一个存储目标串s[]一个存储匹配串p[]一个整形数组存储ne[i]代表如果遇到不匹配应该后退的位置目标串的长度n,匹配串的长度m求匹配串的nefor(int i = 2, j = 0; i <= m; ++i){ while(j && p[j + 1] != p[i]) j = ne[j]; if(p[j + 1] == p[i]) j++; ne[i] = j;}求匹配下标for(int i = 1, j = 0; i <= n原创 2021-01-20 21:59:18 · 54 阅读 · 0 评论 -
算法:滑动窗口(单调队列)
dad原创 2021-01-19 19:32:18 · 249 阅读 · 0 评论