
数据结构与图论
文章平均质量分 51
数据结构与图论
洋芋洋芋洋芋
这个作者很懒,什么都没留下…
展开
-
解题记录 LeetCode 字符串建图问题
通过字符串建立图模型, 通过 bfs 以及 dfs 求解原创 2022-01-23 20:23:04 · 448 阅读 · 0 评论 -
排序算法详细总结
排序算法总结常见的快速排序、归并排序、堆排序、冒泡排序 等属于比较排序 。在排序的最终结果里,元素之间的次序依赖于它们之间的比较。每个数都必须和其他数进行比较,才能确定自己的位置 。在冒泡排序之类的排序中,问题规模为n,又因为需要比较n次,所以平均时间复杂度为O(n²)。在归并排序、快速排序之类的排序中,问题规模通过分治法消减为logN次,所以时间复杂度平均O(nlogn)。比较排序的优势是,适用于各种规模的数据,也不在乎数据的分布,都能进行排序。可以说,比较排序适用于一切需要排序的情况。计数排序、原创 2021-10-07 10:39:20 · 331 阅读 · 0 评论 -
解题记录 LeetCode 最小覆盖子串 滑动窗口较复杂题
题目链接: https://leetcode-cn.com/problems/minimum-window-substring/题意: 给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 “” 。注意:如果 s 中存在这样的子串,我们保证它是唯一的答案。**思路: ** 滑动窗口 维护哈希表 need 和 len, 思路不难, 写起来挺复杂的class Solution { public String原创 2021-07-06 17:17:19 · 94 阅读 · 0 评论 -
解题记录 LeetCode 无重复字符的最长子串 滑动窗口
题目链接: https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/**题意:**给定一个字符串,请你找出其中不含有重复字符的 连续最长子串 的长度。**思路: **其实就是一个队列,比如例题中的 abcabcbb,进入这个队列(窗口)为 abc 满足题目要求,当再进入 a,队列变成了 abca,这时候不满足要求。所以,我们要移动这个队列!如何移动?我们只要把队列的左边的元素移出就行了,直到满足题原创 2021-07-06 16:14:09 · 100 阅读 · 0 评论 -
解题记录 LeetCode 下一个更大元素 II 单调栈
题目链接: https://leetcode-cn.com/problems/next-greater-element-ii/题意:给定一个循环数组(最后一个元素的下一个元素是数组的第一个元素),输出每个元素的下一个更大元素。数字 x 的下一个更大的元素是按数组遍历顺序,这个数字之后的第一个比它更大的数,这意味着你应该循环地搜索它的下一个更大的数。如果不存在,则输出 -1。思路:我们可以使用单调栈解决本题。单调栈中保存的是下标,从栈底到栈顶的下标在数组nums 中对应的值是单调不升的。每次我们移动原创 2021-07-05 11:42:48 · 131 阅读 · 0 评论 -
解题记录 LeetCode 下一个更大元素 单调栈
题目链接: https://leetcode-cn.com/problems/next-greater-element-i/题意: 给你两个 没有重复元素 的数组 nums1 和 nums2 ,其中nums1 是 nums2 的子集。请你找出 nums1 中每个元素在 nums2 中的下一个比其大的值。nums1 中数字 x 的下一个更大元素是指 x 在 nums2 中对应位置的右边的第一个比 x 大的元素。如果不存在,对应位置输出 -1 。思路:由于数组nums1是nums2的子集,整体思路是先原创 2021-07-05 11:16:27 · 77 阅读 · 0 评论 -
解题记录 LeetCode 升序数组转化为二叉搜索树
升序数组转化为二叉搜索树二叉搜索树的中序遍历是升序序列,题目给定的数组是按照升序排序的有序数组,因此可以确保数组是二叉搜索树的中序遍历序列。给定二叉搜索树的中序遍历,是否可以唯一地确定二叉搜索树?答案是否定的。如果增加一个限制条件,即要求二叉搜索树的高度平衡,是否可以唯一地确定二叉搜索树?答案仍然是否定的。我们可以选择中间数字作为二叉搜索树的根节点,这样分给左右子树的数字个数相同或只相差 11,可以使得树保持平衡。如果数组长度是奇数,则根节点的选择是唯一的,如果数组长度是偶数,则可以选择中间位置左边原创 2021-05-12 13:43:36 · 203 阅读 · 0 评论 -
二叉搜索树
什么是二叉搜索树定义:二叉搜索树是一种节点值之间具有一定数量级次序的二叉树,对于树中每个节点:若其左子树存在,则其左子树中每个节点的值都不大于该节点值若其右子树存在,则其右子树中每个节点的值都不小于该节点值查询复杂度观察二叉搜索树结构可知,查询每个节点需要的比较次数为节点深度加一。如深度为 0,节点值为 “6” 的根节点,只需要一次比较即可;深度为 1,节点值为 “3” 的节点,只需要两次比较。即二叉树节点个数确定的情况下,整颗树的高度越低,节点的查询复杂度越低。构造复杂度二叉搜索树的构原创 2021-05-12 12:12:30 · 132 阅读 · 0 评论 -
解题记录 BFS Find a way
Find a wayPass a year learning in Hangzhou, yifenfei arrival hometown Ningbo at finally. Leave Ningbo one year, yifenfei have many people to meet. Especially a good friend Merceki.Yifenfei’s home is...原创 2021-05-12 11:04:32 · 241 阅读 · 0 评论 -
解题记录 DFS 棋盘问题
Description在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C。Input输入含有多组测试数据。每组数据的第一行是两个正整数,n k,用一个空格隔开,表示了将在一个n*n的矩阵内描述棋盘,以及摆放棋子的数目。 n <= 8 , ...原创 2021-05-12 11:04:03 · 142 阅读 · 0 评论 -
解题记录 BFS 拯救行动
描述公主被恶人抓走,被关押在牢房的某个地方。牢房用N*M (N, M <= 200)的矩阵来表示。矩阵中的每项可以代表道路(@)、墙壁(#)、和守卫(x)。英勇的骑士(r)决定孤身一人去拯救公主(a)。我们假设拯救成功的表示是“骑士到达了公主所在的位置”。由于在通往公主所在位置的道路中可能遇到守卫,骑士一旦遇到守卫,必须杀死守卫才能继续前进。现假设骑士可以向上、下、左、右四个方向移动,...原创 2021-05-12 11:03:33 · 187 阅读 · 0 评论 -
解题记录 BFS 地牢大师 三维
Dungeon Master时间限制: 1000MS 内存限制: 65536K提交总数: 61562 接受: 22565Descriptions:你被困在一个3D地牢中且继续寻找最短路径逃生!地牢由立方体单位构成,立方体单位中有的会充满岩石。向上下前后左右移动一个单位需要一分钟。你不能向对角线的四个方向移动且迷宫四周环绕着许多岩石。是否可以逃出地牢?如果可以,则需要多少时间?Input...原创 2021-05-02 13:38:51 · 261 阅读 · 0 评论 -
解题记录 P1137 拓扑排序略微变形
https://www.luogu.com.cn/problem/P1137很显然,每个点的答案是它所有前驱节点的答案加1,即num[i]=max(num[i], num[j]+1);#include <bits/stdc++.h>using namespace std;const int MAXN = 100005;int n, m;struct edge { int to, cost = 1; edge(int to) { this->to = to; }.原创 2021-05-02 13:18:03 · 116 阅读 · 0 评论 -
解题记录 P4017 最大食物链计数 拓扑排序
题意:给你一个食物链 DAG, 求最多有多少条食物链, 对结果取余 8011200280112002思路:想要找到一条 最大食物链 ,那么这条路径的 起点 入度要为0,终点 出度要为0。故:既要记录入度,还要记录出度!现在的问题转换成了,如何找到图中所有 左端点入度为0 且 右端点出度为0 的路径的数量初始化所有入度为 0 的点的答案为1拓扑排序 需要删除的点的答案 都累加到 它可以到达的点 上面去最后累加所有 出度为0的点(最末尾消费者) 的答案,输出即可。为什么要用拓扑排序 而不用搜索原创 2021-05-02 11:33:21 · 107 阅读 · 0 评论 -
最长路
经典Dijkstra 不能求最长路这是因为,Dijkstra算法的大致思想是每次选择距离源点最近的结点加入,然后更新其它结点到源点的距离,直到所有点都被加入为止。当每次选择最短的路改为每次选择最长路的时候,出现了一个问题,那就是不能保证现在加入的结点以后是否会被更新而使得到源点的距离变得更长,而这个点一旦被选中将不再会被更新。例如这次加入结点u,最长路为10,下次有可能加入一个结点v,使得u通过v到源点的距离大于10,但由于u在之前已经被加入到集合中,无法再更新,导致结果是不正确的。经典Dijsktr原创 2021-05-02 10:01:00 · 1583 阅读 · 0 评论 -
解题记录 HDU6201 带负权的最长路 SPFA
transaction transaction transactionTime Limit: 4000/2000 MS (Java/Others) Memory Limit: 132768/132768 K (Java/Others)Total Submission(s): 284 Accepted Submission(s): 125Problem DescriptionKelukin is a businessman. Every day, he travels around cit原创 2021-05-02 09:08:01 · 193 阅读 · 0 评论 -
拓扑排序
拓扑排序有向无环图英文名: Directed Acyclic Graph 简称 DAG性质能 拓扑排序 的图一定是 有向无环图如果有环, 那么环上任意两个节点在任意序列都不满足条件了有向无环图 一定能 拓扑排序判定检验它是否可以进行 拓扑排序 即可。当然也有另外的方法,可以对图进行一遍 DFS, 在得到的 DFS 树上看有没有连向祖先的非树边(返祖边)。如果有的话,那就有环了。拓扑排序拓扑排序的英文名是 Topological sorting。拓扑排序要解决的问题是 给一个图的原创 2021-05-01 12:57:35 · 700 阅读 · 0 评论 -
树的重心
树的重心对于一棵无根树,设其中的一个节点作为根,则可以形成一棵有根树。该树以根为分界,分为若干个子树,设其中最大子树具有的节点数为 x 。所有节点里, x 值最小的节点就是该树的重心,也叫质心。性质以树的重心为根时,所有子树的大小都不超过整棵树大小的一半。树上所有点到某个点的距离和 中,到重心的距离和是最小的;如果有两个重心,那么到它们的距离和一样。把两棵树通过一条边相连得到一棵新的树,那么新的树的重心在连接原来两棵树的重心的路径上。在一棵树上添加或删除一个叶子,那么它的重心原创 2021-04-23 19:40:20 · 84 阅读 · 0 评论 -
树的直径
树的直径图中所有最短路径的最大值即为 直径,可以用两次 DFS 或者树形 DP 的方法在 O(n) 时间求出树的直径。例题:给你一个 n 个节点的树, 求其直径的长度 1 <= n <= 10000解法一:首先对任意一个结点做 DFS 求出最远的结点,然后以这个结点为根结点再做 DFS 到达另一个最远结点。第一次 DFS 到达的结点可以证明一定是这个图的直径的一端,第二次 DFS 就会达到另一端。解法二:我们记录每个节点向下,所能延伸的最远距离 ,和次远距离 ,那么直径就是所有原创 2021-04-23 18:02:01 · 133 阅读 · 0 评论 -
树的存储和遍历
树的存储和遍历存储只记录父结点( 类似并查集 )用一个数组 parent[N] 记录每个结点的父亲结点。这种方式可以获得的信息较少,不便于进行自顶向下的遍历。常用于自底向上的递推问题中。邻接表对于无根树:为每个结点开辟一个线性列表,记录所有与之相连的结点。vector<int> adj[N];对于有根树:方法一:若给定的是无向图,则仍可以上述形式存储。方法二:若输入数据能够确保结点的上下关系,则可以利用这个信息。为每个结点开辟一个线性列表,记录其所有子结点;原创 2021-04-23 17:05:40 · 148 阅读 · 0 评论 -
树的基础概念
树的基础概念有关树的定义森林(forest):每个连通分量(连通块)都是树的图。按照定义,一棵树也是森林。生成树(spanning tree):一个连通无向图的生成子图,同时要求是树。也即在图的边集中选择 n - 1 条,将所有顶点连通。结点的深度(depth):到根结点的路径上的边数。树的高度(height):所有结点的深度的最大值。无根树的叶结点(leaf node):度数不超过 1 的结点。有根树的叶结点(leaf node):没有子结点的结点。有根树父原创 2021-04-23 17:04:56 · 165 阅读 · 0 评论 -
邻接表 + DFS + BFS
DFS + BFS深度优先搜索很简单的, 主要是递归, 复杂度一般很高, 是指数级别的搜索不是一种算法, 而是一种经验, 一种写法, 可以说是暴力传统搜索结构:void dfs(int x, ...) { // 递归终止条件 /* 在当前点对下一个状态进行搜索 { 标记当前点 搜索 取消标记 } */}广度优先搜索也简单, 主要用到了队列, 采用的是横向搜索传统结构:void bfs(int x) { que.pu原创 2021-04-23 16:29:38 · 163 阅读 · 0 评论 -
图的存储
图的存储直接存边使用一个数组(结构体数组)来存边,数组中的每个元素都包含一条边的起点与终点(带边权的图还包含边权)。(或者使用多个数组分别存起点,终点和边权。)应用由于直接存边的遍历效率低下,一般不用于遍历图。在 Kruskal 算法 中,由于需要将边按边权排序,需要直接存边。在有的题目中,需要多次建图(如建一遍原图,建一遍反图),此时既可以使用多个其它数据结构来同时存储多张图,也可以将边直接存下来,需要重新建图时利用直接存下的边来建图。邻接矩阵a[i][j] = 3; 代表 i 到 j 的原创 2021-04-19 19:38:10 · 159 阅读 · 0 评论 -
二分图
二分图最大匹配设 G=(V,E) 是一无向图,若顶点 V 可分割为两个互不相交的子集 (A,B),且图中的每条边(i,j)所关联的两个顶点 i 和 j 分属这两个不同的顶点集 (i ∈ A,j ∈ B),则称图 G 为一二分图。其充要条件是:图 G 中至少存在两个点,且图中所有回路的长度均为偶数。简单来说,就是顶点集 V 可分割为两个互不相交的子集,且图中每条边依附的两个顶点都分属于这两个子集,两个子集内的顶点不相邻。当图中的顶点分为两个集合,有第一个集合中的所有顶点都与第二个集合中的所有顶点相连时原创 2021-04-19 12:48:22 · 214 阅读 · 0 评论 -
最小生成树
最小生成树给你一个图, 求最少的边让图连通, 并且边权和最小思想:先选择最短的边, 然后选择次短的边. (对边进行排序)其中如何判断两个顶点已经连通, 通过并查集来解决#include <bits/stdc++.h>using namespace std;const int MAXN = 505;int pa[MAXN];int find(int x) { int x_root = x; while(x_root != pa[x_root]) { pa[x_root]原创 2021-04-19 12:47:51 · 88 阅读 · 0 评论 -
割点和桥
割点首先 num 数组记录的是时间戳low 数组记录在不通过父顶点时(可以到达父顶点) 能够回到的且时间戳最小的点的时间戳如下图如果有low[v] >= num[u] 其中 u 为 v 顶点的父亲那么说明v 不能绕过 u 回到更早的祖先, 因此u 为割点代码实现如下:#include <bits/stdc++.h>using namespace std;const int MAXN = 505;int n, m, e[MAXN][MAXN], root;int原创 2021-04-19 12:47:20 · 120 阅读 · 0 评论 -
最短路
Floyd 算法for(k=1;k<=n;k++) for(i=1;i<=n;i++) for(j=1;j<=n;j++) if(e[i][j]>e[i][k]+e[k][j]) e[i][j]=e[i][k]+e[k][j];//核心代码,仅仅只有5行这段代码的基本思想就是:最开始只允许经过1号顶点进行中转,接下来只允许经过1和2号顶点进行中转……允许经过1~n号所有顶点进行中转,求任原创 2021-04-19 12:45:44 · 105 阅读 · 0 评论 -
并查集(路径压缩)
并查集注意数组初始化到时候不要初始化为 -1 , 至于原因读读代码就懂啦#include <bits/stdc++.h>using namespace std;const int MAXN = 505;int pa[MAXN];int find(int x) { int x_root = x; while(x_root != pa[x_root]) { //p元素不再选择原来的父亲节点,而是直接选择父亲节点的父亲节点来做为自己新的一个父亲节点 pa[x_ro原创 2021-04-19 12:23:13 · 131 阅读 · 0 评论 -
二分查找及其基本拓展
while(low <= high) { mid = high + (low-high) / 2; //防止high+low爆int if(a[mid] == key)break; if(a[mid] > key)high = mid - 1; else low = mid + 1; }时间复杂度为log2(n)。...原创 2019-12-15 23:18:31 · 226 阅读 · 1 评论