随笔分类 - 算法与数据结构
摘要:单调栈 知识概览 单调栈最常见的应用是找到每一个数离它最近的且比它小的数。 单调栈考虑的方式和双指针类似,都是先想一下暴力做法是什么,然后再挖掘一些性质如单调性,最终可以把目光集中在比较少的状态中,从而达到降低时间复杂度的作用,都是算法优化的一种手段。 对于的情况,更有可能是答案,因此将删掉。最终,
阅读全文
摘要:在数据结构中,栈和队列都属于线性表。栈是先进后出(FILO)的,队列是先进先出(FIFO)的
阅读全文
摘要:知识概览 链表包括单链表和双链表,这里讨论算法题中的链表。为了考虑算法题中对于时间效率的要求,链表通常是用数组模拟成静态链表的形式,速度快。 单链表可以用来写邻接表(包括n个链表),邻接表可以存储树和图,最短路问题、最小生成树问题、最大流问题都可以用邻接表来存储。 双链表用来优化某些问题。 单链表
阅读全文
摘要:区间合并使用贪心算法,对于区间问题,通常需要对左端点排序、右端点排序或者左端点和右端点双关键字排序。区间合并算法的算法步骤: 1. 按照区间左端点排序。 2. 扫描过程中,每次维护一个当前的区间。 题目链接: https://www.acwing.com/problem/content/805/ 代
阅读全文
摘要:离散化是将大范围的数字映射到小范围的区间内,适用于稀疏的区间。 两个问题需要考虑: 1. 原数组中可能有重复元素,需要去重。 2. 如何算出离散化后的值(离散化后保序,使用二分)。 题目链接: https://www.acwing.com/problem/content/804/ 代码: #incl
阅读全文
摘要:如何求n的二进制表示中第k位是几? 1.先把第k位移到最后一位:n >> k 2.看个位是几:x & 1 综合得到:n >> k & 1返回的是n的二进制表示中第k位 题目链接: https://www.acwing.com/problem/content/803/ 题解: 用到lowbit(x)
阅读全文
摘要:双指针算法分为两类:第一类指向一个序列(更多的情况),第二类指向两个序列。 基本的代码框架是: for (i = 0, j = 0; i < n; i++) { while (j < i && check(i, j)) j++; // 每道题目的具体逻辑 } 核心思想:运用单调性等性质,将O(n2)
阅读全文
摘要:差分是前缀和的逆运算 一维差分 对于a1,a2,…,an,构造b1,b2,…,bn,使得ai = b1 + b2 + … + bi。此时,b数组成为a数组的差分,a数组称为b数组的前缀和。 题目链接: https://www.acwing.com/problem/content/799/ 代码模版:
阅读全文
摘要:前缀和思维导图: 一维前缀和算法模版: #include <iostream> using namespace std; const int N = 100010; int n, m; int s[N]; int main() { scanf("%d%d", &n, &m); for (int i
阅读全文
摘要:高精度加法 题目链接: https://www.acwing.com/problem/content/793/ 代码模版: #include <iostream> #include <vector> using namespace std; // C = A + B vector<int> add(
阅读全文
摘要:整数二分 二分的本质并不是单调性,而是从一半满足一半不满足的区间中找到边界点。 模板题: 数的范围 给定一个按照升序排列的长度为n的整数数组,以及q个查询。 对于每个查询,返回一个元素k的起始位置和终止位置(位置从0开始计数)。 如果数组中不存在该元素,则返回 -1 -1。 输入格式 第一行包含整数
阅读全文
摘要:归并排序思维导图: 知识点:如果原序列中两个数的值是相同的,它们在排完序后,它们的位置不发生变化,那么这个排序是稳定的。快速排序是不稳定的,归并排序是稳定的。 快排变成稳定的=>使快排排序数组中的每个数都不同,将ai变成<ai, i>这个二元组,将ai的下标也放进来,使用双关键字排序。 快速排序平均
阅读全文
摘要:快速排序思维导图: 快速排序算法模版: #include <iostream> using namespace std; const int N = 1e5 + 10; int n; int q[N]; void quick_sort(int q[], int l, int r) { if (l >
阅读全文