数据结构与算法
文章平均质量分 95
Java技术一点通
本人计算机软件工程专业在读,擅长于Java后端开发,有多个项目开发经验,业余丰富各种技术栈,大学期间参与软件研发中心研究。荣获2023年CSDN博客之星、CSDN城市之星、阿里云社区专家博主、华为云享专家,致力于新技术的推广与优秀作品的普及。
展开
-
算法基础复盘笔记Day12【贪心算法】—— 区间问题、Huffman树、排序不等式、绝对值不等式、推公式
中位数有非常优秀的性质,比如说在这道题目中,每一个点到中位数的距离,都是满足全局的最有性,而不是局部最优性。具体的来说,我们设在仓库左边的所有点,到仓库的距离之和为 p ,右边的距离之和则为 q,那么我们就必须让p+q的值尽量小。当仓库向左移动的话,p会减少 x,但是 q 会增加 n−x,所以说当为仓库中位数的时候, p+q最小。原创 2023-04-18 17:14:30 · 2024 阅读 · 0 评论 -
算法基础复盘笔记Day11【动态规划】—— 区间DP、计数类DP、树形DP、记忆化搜索
考虑一颗以u为根节点的子树,这颗子树的快乐指数应该是u的函数,并且分两种情况:选u和不选u。状态表示: f[u][1]表示以u 为根节点的子树并且包括u的总快乐指数,f[u][0] 表示以u为根节点的子树并且不包括u的总快乐指数。状态计算:记点u的子节点是s- 选 $u$,f[u][1] += $\sum\limits_{}^{}$f[s][0];- 不选 $u$,f[u][0] += $\sum\limits_{}原创 2023-04-15 22:58:38 · 1926 阅读 · 0 评论 -
算法基础复盘笔记Day10【动态规划】—— 线性DP
最长上升子序列这道题的时间复杂度是 O(n^2),用在这道题会超时。如果把内层循环改为 二分查找,就能把内存查找时间降为 logn,则时间复杂度O(nlogn)。但是,二分查找的前提是有序序列,故增加一个 b 数组,用来记录上升子序列。关键问题:动态更新 b 数组。考虑新进来一个元素 $a[i]$:- `大则添加`:如果 `a[i] > b[len]`,直接让 `b[++ len] = a[i]`。即 $b$ 数组的长度增加1,并且添加了一个元素;-原创 2023-04-13 08:23:59 · 1836 阅读 · 2 评论 -
算法基础复盘笔记Day09【动态规划】—— 背包问题
版本一: 二维数组(1)状态 f[i][j]定义:前i 个物品,背包容量是 j 下的最优解(最大价值):- 当前的状态依赖于之前的状态,可以理解为从初始状态 f[0][0] = 0开始决策,有 N 件物品,则需要 N 次决 策,每一次对第 i 件物品的决策,状态 f[i][j]不断由之前的状态更新而来。(2) 当前背包容量不够(j < v[i]),没得选,因此前 i 个物品最优解即为前 i−1 个物品最优解:原创 2023-04-10 14:40:19 · 2235 阅读 · 0 评论 -
算法基础复盘笔记Day08【数学知识】—— 质数、约数、快速幂
质数定义:一个大于1的自然数,除了1和它本身外,不能被其他自然数整除,换句话说就是该数除了1和它本身以外不再有其他的因数,这个数就是质数。给定一个数 x,判断 x 是否为质数:用 x 除以 [2 ,x - 1] 中的每个数,如果出现了余数为 0, 则这个数不是质数,如果没有出余数为 0,则这个数是质数。优化:一个数 x 分解成两个数的乘积,则这两个数中,一定有一个数大于{x},一个数小于{x}。原创 2023-04-08 10:17:51 · 1157 阅读 · 1 评论 -
算法基础复盘笔记Day07【搜索与图论】—— Prim、Kruskal、染色体判定二分图、匈牙利算法
二分图: 如果一张无向图的 $N$ 个节点可以分为 A,B两个不相交的非空集合,并且同一集合内的点之间没有边相连,那么称该无向图为二分图。定理:二分图不存在奇环(长度是奇数的环) 因为每一条边都是从一个集合走到另一个集合,只有走偶数次才可能回到同一个集合。染色法:我们可以使用染色法来判定二分图。即尝试用两种颜色标记图中的节点,当一个点被标记后,所有与它相邻的节点应该标记与它相反的颜色,若标记过程产生冲突,则说明图中存在奇环,即不存在二分图。原创 2023-04-07 07:55:54 · 1473 阅读 · 0 评论 -
算法基础复盘笔记Day06【搜索与图论】—— Dijkstra、bellman-ford、spfa、Floyd
Dijkstra算法的 堆优化——用优先队列维护被更新的点的集合。创建一个 pair类型的小根堆 heap{距离, 点},这样距离最小的点一定在堆顶;初始化,将第一个点的 dist 值设置为0,其他点的 dist值为正无穷,把{0, 1}入堆;弹出距离最短的堆顶元素 u,若 u扩展过则跳过,否则打标记;4. 对 $u$ 的所有出边进行松弛操作,把 `{d[v], v}` 压入堆中;5. 重复步骤3、4,知道队列为空;6. 最原创 2023-03-25 09:27:35 · 1006 阅读 · 0 评论 -
算法基础复盘笔记Day05【搜索与图论】—— DFS、BFS、树与图的深度优先遍历、树与图的广度优先遍历、拓扑排序
定义 g[N][N] 来存放地图,d[N][N] 来表示每一个点到起点的距离,用队列来存储要访问的点;初始化:将每个点到起点的距离设置为-1,表示该点没有被访问过;从队列中取出队头元素即为要访问的点,枚举该点的上、右、下、左四个方向,如果这四个方向有在边界内的并且是空地还没有被走过的,则将该点到起点的距离加1,并且将新坐标加入队列中;最后返回右下角到起点的距离即可。原创 2023-03-20 08:49:03 · 361 阅读 · 0 评论 -
算法基础复盘笔记Day04【数据结构】—— KMP、字典树(Tire)、并查集、堆、哈希表
并查集是一种树形的数据结构。并查集支持的两个操作:合并:将两个子集合并成一个集合。查找:确定某个元素在哪个集合。带路径压缩的查找:根节点是集合的代表,查找就是找到元素所在集合的根。1. 如果父节点等于自己,则找到了根并返回;2. 如果还没有找到根,则继续递归查找;3. 在返回的路上,顺带修改各节点的父节点为根。原创 2023-03-18 08:11:28 · 1864 阅读 · 0 评论 -
算法基础复盘笔记Day03【数据结构】—— 单链表、双链表、栈、队列、单调栈、单调队列
维护一个单调递增栈: 在保持栈内元素单调递增的前提下(如果栈顶元素大于要入栈的元素,将将其弹出),将新元素入栈。对于栈内元素来说:在栈内自己左边的数就是数组中左边第一个比自己小的元素;如果当前栈为空并且栈顶元素大于或等于当前元素,则将弹出栈顶元素,将当前元素压入栈中。因为当前元素比栈顶元素还小,所以永远用不到栈顶元素。原创 2023-03-15 09:54:55 · 1631 阅读 · 3 评论 -
算法基础复盘笔记Day02【算法基础】—— 前缀和与差分、双指针算法、位运算、离散化、区间合并
差分思想和前缀和是相反的。首先我们先定义数组a, 其中a[1],a[2]…a[n]作为前缀和。然后构造数组`b,b[1],b[2]…b[n]`为差分数组。其中通过差分数组的前缀和来表示a数组,即a[n] = b[1] + b[2]+…+b[n]。一维差分数组的构造也很简单,即a[1] = b[1], b[2] = a[2] - a[1], b[n] = a[n] - a[n-1];原创 2023-03-13 09:35:18 · 980 阅读 · 0 评论 -
算法基础复盘笔记Day01【算法基础】—— 快速排序、归并排序、二分、高精度
首先设定一个**分界值**,将数组分为左右两部分。将大于或等于分界值的数据集中到数组右边,小于分界值的数据集中到数组的左边。此时,左边部分中各元素都小于分界值,而右边部分中各元素都大于或等于分界值。左边和右边的数据可以独立排序。对于左侧的数组数据,又可以取一个分界值,将该部分数据分成左右两部分,同样在左边放置较小值,右边放置较大值。右侧的数组数据也可以做类似处理。重复上述过程,可以看出,这是一个递归定义。通过递归将左侧部分排好序后,再递归排好右侧部分的顺序。当左、右两个部分各数原创 2023-03-10 09:38:18 · 933 阅读 · 0 评论