数据结构与算法
文章平均质量分 50
ALuckyA
这个人什么都没有留下…
展开
-
差分模板题
题目描述 输入 3 2 1 2 3 1 2 4 3 3 -2 输出 5 6 1 题目分析 O(n)复杂度必定会超时 所以需要找到一个O(1)复杂度的解题方式 此时想到前缀和 对于任意一个[l,r]的子序列,只需将a[l]加上k,a[r]减去k,再应用前缀和即可 #include<bits/stdc++.h> using namespace std; typedef long long ll; int n,m; const int N = 1e5 + 5; ll arr[N],sum[N];原创 2022-01-10 12:11:16 · 299 阅读 · 0 评论 -
双指针小算法
class Solution { public: int maxArea(vector<int>& height) { int ans = 0; int i = 0, j = height.size() - 1; while (i < j) { int sum = min(height[i], height[j]) * (j - i); ans = max(ans, sum); if (height[i] <= height.原创 2020-10-14 01:29:34 · 108 阅读 · 0 评论 -
寻找两个正序数组的中位数
题目描述 题目链接 给定两个大小为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的中位数。 示例 1: 输入:nums1 = [1,3], nums2 = [2] 输出:2.00000 解释:合并数组 = [1,2,3] ,中位数 2 示例 2: 输入:nums1 = [1,2], nums2 = [3,4] 输出:2.50000 解释:合并数组 = [1,2,3,4] ,中位数 (2 + 3) / 2 = 2.5 示例 3: 输入:nums1 = [0,0原创 2020-10-11 14:22:08 · 93 阅读 · 0 评论 -
Moore Voting
Problem Description: Given an array of size n, find the majority element. The majority element is the element that appears more than ⌊ n/2 ⌋ times. You may assume that the array is non-empty and the majority element always exist in the array. Example 1: In原创 2020-09-10 20:03:19 · 100 阅读 · 0 评论 -
Manhattan Distance
Formula dis(i,j)=|xi-xj|+|yi-yj| E.G. Input The input consists of at most 100 datasets, each in the following format. h w r1 … rh s The two integers h and w in the first line are the height and the width of the OSK, respectively. They are separated by a原创 2020-08-11 11:18:50 · 248 阅读 · 0 评论 -
Tarjan‘s Algorithm Practice
Tarjan’s Algorithm——求强连通分量的线性时间的算法 如果有两个vertex可以互相到达,那么则称两个顶点强连通 若graph中任意两个顶点都可以互相到达,那么则称这个图为一个强连通图 其中的一个子图称为强连通分量 基于对图的dfs,每个强连通分量是搜索树中的一颗子树 维护两个数组dfn[N],low[N],dfn[x]表示顶点x的时间戳,low[x]表示x或x的子树能够回溯的栈中最小的次序 模板题1 题目描述 给出一个 n 个点,m 条边的无向图,求图的割点。 输入格式原创 2020-08-20 20:47:06 · 206 阅读 · 0 评论 -
SPFA Algorithm Template
#define _CRT_SECURE_NO_WARNINGS #include<bits/stdc++.h> using namespace std; const int LEN = 2e5 + 5; struct Edge { int begin, end, weight; int next; }edge[LEN]; int n, m, head[LEN], dis[LEN]; int s, e; bool vis[LEN]; int cnt[LEN]; queue<int>原创 2020-08-03 23:47:09 · 160 阅读 · 0 评论 -
Floyed Practice
一.入门级别 城市交通费 【问题描述】 有 n 个城市,编号 1~n。其中 i 号城市的繁华度为 pi。省内有 m 条可以双向同行的高速 公路,编号 1~m。编号为 j 的高速公路连接编号为 aj 和 bj 两个城市,经过高速公路的费用 是 wj。若从城市 x 出发到某城市 y,除了需要缴纳高速公路费用,还要缴纳“城市建设费” (为从 x 城市到 y 城市所经过的所有城市中繁华度的最大值,包括 x 和 y 在内)。 现提出 q 个询问,每个询问给出一组 x 和 y,你需要回答从 x 出发到 y 城市,所需要原创 2020-08-02 10:33:46 · 434 阅读 · 0 评论 -
Dijkstra Algorithm
Dijkstra算法 求解最短路径问题 用于求解一个结点到其余各节点的最短路径 运用广度优先搜索思想 算法思想 假设出发顶点为v,顶点集合为V{v1,v2,…},v到V中各顶点距离构成的集合为D{…} 从D集合中找到di最小的一个移除集合(除它本身),并且移出V中所对应的顶点vi D中元素进行更新,di=min(di,从v出发经过上次步骤所得到的一系列vi到达D中未被访问过顶点的距离) 重复执行上述步骤,直到找到所有的目标顶点 具体实现 const int maxNum = 100; const in原创 2020-08-01 15:12:09 · 235 阅读 · 0 评论 -
筛选素数算法
素数筛选步骤 首先,将数组isPrime[]置为true 然后,令isPrime[0]=isPrime[1]=false 依次用2,3,5,7…进行筛选,只要是他们的倍数就置为false 具体实现 const int LEN = 10000000; int isPrime[LEN]; void init() { memset(isPrime, 1, sizeof(isPrime)); isPrime[0] = isPrime[1] = 0; for (int i = 2; i <= sqrt原创 2020-07-30 00:27:58 · 286 阅读 · 0 评论 -
Manacher算法
Manacher算法 处理字符串中关于回文串的问题 优点: 可以以O(n)的时间,维护一个数组,依次计算出字符串中每一个字符所对应的最长的回文串半径 大致思路: 在原字符串的每两个相邻字符中插入一个不同于原字符串中字符的分隔符,一般用‘#’ 同时在原字符串的首尾添加上不同的分隔符 通过这种操作 使得原字符串的size无论是奇数还是偶数,最后都会变成奇数 (previous_size*2+3) 模板题 题目描述 给出一个只由小写英文字符a,b,c,…y,z 组成的字符串 S ,求 S 中最长回文串的长度 字符原创 2020-07-23 21:02:02 · 146 阅读 · 0 评论 -
Kruskal算法
Kruskal算法 求最小生成树的一种算法 Kruskal算法: 以边为中心 首先按照所提供边的权值进行升序排序(连接n个顶点在不形成回路的情况下形成n-1条边) 构造一个只有n个顶点的生成树,按照边权值的大小依次加入到这颗生成树中,而且不能产生回路,直到加了n-1条边形成一颗MST为止 实现代码 #include<bits/stdc++.h> using namespace std; const int LEN = 50; int n,m;//n代表顶点个数 m代表原先边数 int nu原创 2020-07-18 11:30:57 · 211 阅读 · 0 评论 -
Prim算法
Prim算法 求最小生成树的一种算法 最小生成树(MST): 给定一个带权的无向连通图,要求得到一颗生成树,使得树上所有边的权值相加和最小 Prim算法: 以点为中心 先选定一个顶点作为生成树的起始点,并且将该顶点标记为已访问过 然后用这颗生成树中已有的顶点分明去寻找与它相邻且未被它访问过的顶点,记录下各自的权值,选择其中带有最小权值的顶点,并把它标记为已访问过 重复第二部操作,直到所有的顶点均被访问,此时有n-1条边 Prim算法案例 T1 题目描述 某国有n个城市,它们互相之间没有公路相通,因此交通原创 2020-07-17 20:09:22 · 317 阅读 · 0 评论 -
单调队列
单调队列特点 队列中的元素单调 运用deque容器实现,保证能在两端操作 由于每个元素最多进队一次,出队一次,所以O(1) 单调队列例题 输入输出样例 8 3 1 3 -1 -3 5 3 6 7 -1 -3 -3 -3 3 3 3 3 5 5 6 7 在线OJ 暴力搜索反正是会TLE,考虑单调队列O(n) #define _CRT_SECURE_NO_WARNINGS #include<bits/stdc++.h> using namespace std; int n, k, p[原创 2020-07-16 11:28:49 · 125 阅读 · 0 评论 -
开关问题
1.开灯 题目背景 该题的题目是不是感到很眼熟呢? 事实上,如果你懂的方法,该题的代码简直不能再短。 但是如果你不懂得呢?那。。。(自己去想) 题目描述 首先所有的灯都是关的(注意是关!),编号为1的人走过来,把是一的倍数的灯全部打开,编号为二的的把是二的倍数的灯全部关上,编号为3的人又把是三的倍数的灯开的关上,关的开起来……直到第N个人为止。 给定N,求N轮之后,还有哪几盏是开着的。 输入格式 一个数N,表示灯的个数和操作的轮数 输出格式 若干数,表示开着的电灯编号 输入输出样例 5 1 4 1<原创 2020-07-14 23:54:40 · 978 阅读 · 0 评论 -
二叉树习题
①考察深度 运用了递归的思想从第一个结点,深度为1开始DFS #define _CRT_SECURE_NO_WARNINGS #include<bits/stdc++.h> using namespace std; const int LEN = 1e7 + 5; struct Node { int left; int right; }node[LEN]; int ans; void dfs(int root, int depth); int main() { int n; cin原创 2020-07-14 14:05:05 · 204 阅读 · 0 评论 -
八皇后问题
回溯算法经典案例——八皇后问题 题目描述: 在8*8的国际象棋上摆放八个皇后,使任意两个皇后都不能处于同一行,同一列或同一斜线上,问有多少种摆法 idea: 先把第一个黄后放在(1,1) 再把第二个皇后放在(2,1), (2,2),…直到找到一个解为止 continue 只要得到一个答案,就会开始回溯,即将第一个皇后再放置在第一行的其他列,反复上述过程 核心代码 void Print(); void Print() { for (int i = 0; i < n; i++) { print原创 2020-07-11 17:14:09 · 806 阅读 · 0 评论 -
小算法
一.求模算法 资料来源:运算规则 模运算与四则运算有点相似,except除法 (a+b)%p=(a%p+b%p)%p; (a-b)%p=(a%p-b%p)%p; (a·b)%p=(a%p·b%p)%p; a ^ b % p = ((a % p)^b) % p 例题链接:Fibonacci Again AC code #define _CRT_SECURE_NO_WARNINGS #include<iostream> using namespace std; //(a+b)%p=(a%p+b原创 2020-07-10 23:41:31 · 191 阅读 · 0 评论 -
动态规划练习
动态规划算法核心思想 将大问题划分成若干个子问题,从而一步步获取最优解的处理算法 与分治算法相同的是,均将待求解问题划分成一个个小子问题,从这些子问题得到原问题的解 与分治算法不同的是,动态规划得到一系列的子问题是互相有关联的,而不是独立存在 经典背包例题 ——01背包 题目描述 金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间他自己专用的很宽敞的房间。更让他高兴的是,妈妈昨天对他说:“你的房间需要购买哪些物品,怎么布置,你说了算,只要不超过NN元钱就行”。今天一早金明就开始做预算,但是他想买的原创 2020-07-07 20:13:35 · 251 阅读 · 0 评论 -
大数加法
A+B大数加法 题目来源 A+B高精 题目描述:高精度加法,相当于a+b problem,不用考虑负数. 看到这题时,就想到用string来解决,也想到了之前做过的一道题目,很相似的A+B 当时的AC代码 #define _CRT_SECURE_NO_WARNINGS #include<cstdio> #include<iostream> #include<string> #include<algorithm> using namespace std原创 2020-07-05 21:18:54 · 198 阅读 · 0 评论 -
图(plus)DFS(e.g.)
图的专有名词 顶点(vertex) 边(edge) 路径 无向图 有向图 带权图 边带权值** ABCDE均为顶点,AB BC等均为边 A到C的路径有A->B->C,A->C 上图为一个无向图,顶点之间的连接无方向 顾名思义,有向图就是顶点之间的连接有方向 图的表示方式 1.邻阶矩阵(二维数组) 2.邻接表(链表) DFS DFS,即深度优先搜索 首先访问第一个邻接结点,再以这个结点作为初始访问结点,访问它的第一个邻接结点,是一个递归的过程 思路 访问初始结点,并标记它已被访问 查找它原创 2020-07-04 19:37:34 · 168 阅读 · 0 评论 -
二叉树Notes
相比数组与链表 1.数组存储方式: 优:可以直接通过下标访问数组元素,效率高。对于有序数组,直接采用二分搜索就OK 缺:增删效率太低,因为移动了差不多整个数组 2.链表存储方式: 优:增删效率高 缺:检索效率低,每次要从head结点开始搜索 3.树存储方式: 能够提高存储,读取数据的效率 二叉树 这颗二叉树共有三层, ...原创 2020-07-02 13:57:08 · 642 阅读 · 0 评论 -
最近点对问题
分而治之 题目来源:Quoit Design Problem Description Have you ever played quoit in a playground? Quoit is a game in which flat rings are pitched at some toys, with all the toys encircled awarded. In the field of Cyberground, the position of each toy is fixed, and t原创 2020-07-02 00:48:37 · 274 阅读 · 0 评论 -
DP算法实践
DP(动态规划算法初步) 情形一 题目来源(http://acm.hdu.edu.cn/showproblem.php?pid=1003) 题面大概意思就是要找到最大和的子数列,并且输出其和,其起始索引+1,其终止索引+1 做这道题时,我一开始的思路是 直接暴力遍历找到所求解 上代码 #define _CRT_SECURE_NO_WARNINGS #include<bits/stdc++.h> using namespace std; int p[100005]; int main() {原创 2020-07-01 00:20:09 · 2050 阅读 · 2 评论 -
快速排序
快排 最近在看排序算法 看到快排时,看到有三种不同思想的的快排算法 这里 就选取一种我认为比较好接受的 时间复杂度 平均时间复杂度O(nlogn) 最坏情况下为O(n^2),与冒泡排序一样,同属于交换排序 且它是对冒泡排序的一种改进 思路 首先通过一次排序将要进行排序的数据分成两个部分,其中,左边的所有数据都比右边的数据要大 然后递归进行,对左边部分快排,再对右边部分快排 代码 总体设计 int findMid(int* arr, int left, int right); void qSort(int*原创 2020-06-30 16:51:08 · 175 阅读 · 0 评论 -
堆排序
排序之堆排序 看了B站的数据结构中的堆排序后, 在感慨了堆排序的高效(排序八百万个数据只需3seconds) 就juo得自己应该记下些什么 堆排序时间复杂度 无论在哪种情况下好像均为O(nlogn) 空间复杂度为O(1) 并且在《数据结构与算法分析》这本书中看到 堆排序是一个非常稳定的算法 且与树结构联系紧密 堆结构 堆是一种完全二叉树 若升序,则使用大顶堆(每个父结点的值均大于等于子结点的值) 若降序,则使用小顶堆(每个父结点的值均小于等于子节点的值) 以升序为例,使用大顶堆 ...原创 2020-06-28 23:24:04 · 182 阅读 · 0 评论 -
6-1单链表逆转
@@数据结构与算法题目集 单链表逆转初步想法 在数据结构与算法这门课程中终于与熟悉的链表打了个照面,首先看到单链表逆转这道题,脑海里有闪现出几种solutions Solution 1:重新创建一个链表,以原链表为辅助,给新链表添加数据,再返回这个新链表 Solution2:不动节点位置,只改变数据域,即对称swap数据 However 根据这道题的意思,似乎只有Solution1才是一个good idea,毕竟人家函数头都给出来了… 全新的界面设计 ,将会带来全新的写作体验; 在创作中心设置你喜爱的代码原创 2020-06-28 22:22:42 · 283 阅读 · 0 评论