算法模板
文章平均质量分 75
持续更新学习过程中遇到的算法模板!!!
爱跑步的程序员~
大家好,我是一名大二的后端开发学生,专注于Java、Spring Boot、Spring Cloud、高并发和微服务。我热衷于数据结构和算法,并在GitHub上分享我的开源项目。我在CSDN上记录和分享我的学习过程。我相信编程是解决问题和创造价值的工具。欢迎关注我,一起学习,一起进步!
展开
-
P1048 [NOIP2005 普及组] 采药
此问题本质上是一个0-1背包问题,其中每个物品(草药)都有一定的重量(采集所需时间)和价值(草药价值)。目标是在给定的容量(总采集时间)下,使背包中物品的总价值最大化。由于问题规模较小$(M \leq 100,T \leq 1000)$,我们可以通过动态规划来解决这个问题。关键在于状态转移方程的构建,以及如何有效地利用空间。原创 2024-06-09 20:02:05 · 572 阅读 · 0 评论 -
300. 最长递增子序列
本题要求找出给定数组中最长的递增子序列的长度。一个有效的策略是使用动态规划,但更高效的方法是结合二分查找和动态规划的思想,利用“二分查找”来减少时间复杂度。原创 2024-06-06 17:21:57 · 274 阅读 · 1 评论 -
204. 计数质数
我们可以使用埃拉托斯特尼筛法(Sieve of Eratosthenes)来解决这个问题。这个算法的基本思想是从2开始,将每个质数的各个倍数,标记为合数。一个合数总是可以表示为质数的倍数,所以,如果我们在发现一个新的质数时,将其未来可能的倍数都标记为合数,那么到最后剩下的就是质数。原创 2024-05-09 23:30:00 · 357 阅读 · 0 评论 -
P3385 【模板】负环
这是一个经典的负环检测问题,可以使用Bellman-Ford算法配合SPFA优化来解决。Bellman-Ford算法的基本思想是通过对所有边的松弛操作,逐步减小源点到其他各点的距离。如果在进行n次松弛操作后,还能继续减小源点到某个点的距离,那么图中存在负环。原创 2024-05-07 16:14:43 · 378 阅读 · 0 评论 -
P2910 [USACO08OPEN] Clear And Present Danger S
这是一个图论问题,我们需要找到从一个城市到另一个城市的最短路径。我们可以使用Floyd-Warshall算法来解决这个问题。首先,我们需要构建一个距离矩阵,然后使用Floyd-Warshall算法来更新这个矩阵,最后我们可以通过这个矩阵来找到最短路径。原创 2024-05-06 14:05:58 · 693 阅读 · 0 评论 -
A*算法求最短路
这是一个经典的A寻路算法问题。A算法是一种启发式搜索算法,题解结合了最佳优先搜索和Dijkstra算法的优点,能够在寻找最短路径的过程中避免大量的无谓搜索,提高了效率。在这个问题中,我们需要找到从起点到终点的最短路径。我们可以使用A*算法,通过一个优先队列(堆)来存储待搜索的节点,每次从堆中取出代价最小的节点进行搜索,直到找到终点。原创 2024-05-05 19:46:22 · 662 阅读 · 1 评论 -
1368. 使网格图至少有一条有效路径的最小代价
这道题目可以使用01bfs算法来解决。我们可以将起点和终点看作是两个不同的状态,然后使用BFS来搜索最小代价路径。在搜索过程中,我们需要记录到达每个状态的最小代价。原创 2024-02-05 12:21:33 · 779 阅读 · 0 评论 -
239. 滑动窗口最大值
这个问题可以使用一个数据结构叫做单调队列来解决。单调队列是一种特殊的队列,它可以在 O(1) 的时间复杂度内获取队列中的最大值(或最小值)。在这个问题中,我们可以从左到右遍历数组,将每个数字加入到单调队列中。同时,我们需要保持单调队列的第一个元素始终是当前窗口的最大值。原创 2024-04-14 11:50:40 · 341 阅读 · 0 评论 -
AcWing 2. 01背包问题
这是一个经典的动态规划问题,也被称为01背包问题。我们有n个物品,每个物品有自己的体积和价值。我们的目标是在不超过背包总体积的情况下,选择一些物品,使得这些物品的总价值最大。我们可以使用动态规划的方法来解决这个问题。我们定义dp[i][j]为在前i个物品中选择,且总体积不超过j的情况下,能够得到的最大价值。然后我们可以根据第i个物品是否被选择,来更新dp[i][j]。原创 2024-03-18 08:38:23 · 739 阅读 · 0 评论 -
AcWing 895. 最长上升子序列
这是一个经典的动态规划问题,求解最长上升子序列。我们有一个序列,我们的目标是找到这个序列中的一个最长的上升子序列。我们可以定义dp[i]为以第i个元素结尾的最长上升子序列的长度。然后我们可以根据dp[j] (j < i) 来更新dp[i]。原创 2024-03-14 16:26:52 · 352 阅读 · 0 评论 -
802. 区间和
这是一个离散化+前缀和的问题。我们需要处理两种操作:添加一个数和查询一个区间的和。由于数的范围可能非常大,但是操作的数量相对较小,我们可以将所有出现的数进行离散化处理。然后用一个数组存储每个离散化后的数的数量,再用一个前缀和数组存储从小到大到当前数的总数量。这样查询区间和的操作就可以通过前缀和数组在O(1)的时间复杂度内完成。原创 2024-03-08 15:23:51 · 761 阅读 · 0 评论 -
AcWing 94. 递归实现排列型枚举
这是一个经典的排列型枚举问题,我们需要找出所有可能的排列。我们可以使用深度优先搜索(DFS)来解决这个问题。在每一层递归中,我们尝试所有未使用的数字,然后将其标记为已使用,然后进入下一层递归。当我们返回到当前层时,我们需要将数字标记为未使用,以便在后续的搜索中可以再次使用。原创 2024-03-07 13:16:36 · 930 阅读 · 0 评论 -
AcWing 93. 递归实现组合型枚举
这是一个组合型枚举问题,我们需要找出从1到n的整数中选出m个整数的所有组合。这个问题可以通过深度优先搜索(DFS)来解决。我们从1开始,每次选择一个数,然后在剩下的数中继续选择,直到选择了m个数。原创 2024-03-07 10:03:56 · 922 阅读 · 0 评论 -
AcWing 803. 区间合并
这是一个区间合并的问题。我们需要找出尽可能多的不相交的区间。首先,我们将所有的区间按照左端点从小到大进行排序。然后,我们遍历所有的区间,如果当前区间的左端点大于上一个区间的右端点,那么我们就可以选择这个区间,否则我们就跳过这个区间。原创 2024-03-05 00:15:00 · 860 阅读 · 0 评论 -
AcWing 800. 数组元素的目标和
这是一个双指针问题。我们有两个排序数组,我们需要找到两个数,一个来自每个数组,它们的和等于目标值。我们可以在第一个数组中从左到右遍历,同时在第二个数组中从右到左遍历。如果当前的和大于目标值,我们就将第二个数组的指针向左移动;如果当前的和小于目标值,我们就将第一个数组的指针向右移动。当找到和等于目标值的两个数时,我们就可以停止遍历。原创 2024-03-05 07:15:00 · 482 阅读 · 0 评论 -
AcWing 799. 最长连续不重复子序列
这是一个求最长连续不重复子序列的问题。我们可以使用双指针(滑动窗口)的方法来解决。我们维护一个窗口,并使用一个数组来记录窗口内元素的出现次数。当窗口右端的元素在窗口内出现次数大于1时,我们就移动窗口的左端,直到窗口内所有元素都不重复。在这个过程中,我们记录下窗口的最大长度,这就是我们要找的最长连续不重复子序列的长度。原创 2024-03-04 13:08:43 · 335 阅读 · 0 评论 -
798. 差分矩阵
这是一个差分矩阵的问题。差分矩阵是一种用于处理区间修改问题的数据结构,它可以在O(1)的时间复杂度内完成区间的修改操作,然后在O(n)的时间复杂度内完成所有元素的更新操作。原创 2024-03-02 14:48:59 · 967 阅读 · 0 评论 -
P4231 三步必杀
这个问题可以使用等差数列差分的思想来解决。等差数列差分主要适用于频繁对原始数组的某个区间进行增减。原创 2024-02-28 10:09:29 · 497 阅读 · 0 评论 -
830. 单调栈
这是一个单调栈的问题。单调栈是一种特殊的栈结构,它的特点是栈中的元素保持单调性。在这个问题中,我们需要找到每个元素左边第一个比它小的元素,这就需要使用到单调递增栈。原创 2024-02-26 00:45:00 · 362 阅读 · 0 评论 -
213. 打家劫舍 II
这是一个动态规划问题。由于房屋是环形排列的,所以第一个房子和最后一个房子只能选择一个偷窃,因此可以分为两个子问题: 偷窃第一个房子,那么就不能偷窃最后一个房子,问题就变为了求解 [1, n-2] 的最大值。不偷窃第一个房子,那么就可以偷窃最后一个房子,问题就变为了求解 [2, n-1] 的最大值。在每个子问题中,我们使用动态规划的方法,定义一个一维数组 dp,其中 dp[i] 表示到第 i 个房子时能偷窃到的最大金额。原创 2024-02-25 09:28:47 · 504 阅读 · 0 评论 -
790. 数的三次方根(浮点二分模板)
这是一个使用二分查找法来计算一个数的立方根的问题。二分查找法是一种在有序数组中查找特定元素的搜索算法。搜索过程从数组的中间元素开始,如果中间元素正好是目标值,则搜索过程结束;如果目标值大于或小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较。如果在某一步骤数组为空,则代表找不到目标值。原创 2024-02-12 01:00:00 · 809 阅读 · 0 评论 -
789. 数的范围(二分模板)
这是一个二分查找的问题,我们需要找到数组中等于给定值的最左边和最右边的元素的位置。我们可以使用两次二分查找来解决这个问题,一次查找最左边的元素,一次查找最右边的元素。原创 2024-02-11 11:39:42 · 934 阅读 · 0 评论 -
牛客单调栈结构(进阶)
这是一个单调栈的问题。单调栈是一种特殊的栈结构,它的特点是栈中的元素保持单调性。在这个问题中,我们需要找到每个元素左边和右边第一个比它小的元素。我们可以使用一个单调递减的栈来解决这个问题。我们从左到右遍历数组,对于每个元素,我们将其与栈顶元素进行比较。如果当前元素小于栈顶元素,那么我们就找到了栈顶元素右边第一个比它小的元素,我们可以将栈顶元素出栈,并记录下这个信息。然后我们继续将当前元素与新的栈顶元素进行比较,直到当前元素大于栈顶元素或者栈为空,然后我们将当前元素入栈。原创 2024-02-24 21:30:00 · 864 阅读 · 0 评论 -
198. 打家劫舍
这是一个经典的动态规划问题。我们需要找到一种方法,使得在不触发警报的情况下,能够偷到的最大金额。我们不能偷相邻的房子,所以如果我们决定偷某个房子,那么我们就不能偷它的前一个房子。原创 2024-02-20 21:00:09 · 566 阅读 · 0 评论 -
28. 找出字符串中第一个匹配项的下标
这个问题可以通过使用KMP(Knuth-Morris-Pratt)算法来解决。KMP算法是一种改进的字符串匹配算法,它的主要思想是当子串与目标字符串不匹配时,能知道一部分已经匹配的字符,利用这些信息避免从目标字符串的头部再去做匹配。原创 2024-02-17 01:15:00 · 1603 阅读 · 0 评论 -
AcWing 787. 归并排序
归并排序是一种分治算法。首先将数组分为两半,然后对每一半进行排序,最后将两个已排序的部分合并在一起。这个过程会递归地应用到每一半。原创 2024-02-16 07:15:00 · 1726 阅读 · 0 评论 -
1.蓝桥勇士
这是一个典型的动态规划问题,我们可以使用最长递增子序列(LIS)的思想来解决。我们可以定义一个数组dp,其中dp[i]表示以第i个对手结束的最长挑战序列的长度。对于每一个对手,我们都尝试将其加入到所有在其之前的对手所能形成的挑战序列中,如果当前对手的战力值大于前面对手的战力值,那么就可以将其加入到挑战序列中,更新dp[i]的值。最后,我们只需要找出dp数组中的最大值,就是小明最多会挑战的对手数量。原创 2024-02-14 17:52:05 · 360 阅读 · 0 评论 -
796. 子矩阵的和
这是一个二维前缀和的问题。二维前缀和的主要思想是预处理出一个二维数组,使得每个位置(i, j)上的值表示原数组中从(0, 0)到(i, j)形成的子矩阵中所有元素的和。这样,对于任意的子矩阵(x1, y1)到(x2, y2),我们可以通过四个前缀和的值快速计算出其和。原创 2024-02-13 11:24:22 · 1333 阅读 · 0 评论 -
79. 单词搜索
我们首先遍历二维数组board的所有元素,对于每一个元素,我们都调用一次深度优先搜索函数dfs。在dfs函数中,我们首先检查当前的字符是否与单词中的当前字符相同,如果不相同,那么我们就直接返回false。如果相同,那么我们就在四个方向(上、下、左、右)上进行搜索。如果在任何一个方向上都无法找到一个有效的路径,那么我们就回溯到上一个字符,并尝试在其他的方向上进行搜索。原创 2024-02-14 02:45:00 · 2033 阅读 · 0 评论 -
797. 差分
这是一个差分数组的问题。差分数组的主要适用场景是频繁对原始数组的某一个区间进行增减操作。这种操作是区间修改操作,在这种操作下,差分数组只需要对区间的两个端点进行操作,时间复杂度为O(1)。 在这个问题中,我们需要对数组的某个区间进行加法操作,然后输出修改后的数组。我们可以使用差分数组来解决这个问题。原创 2024-02-12 20:02:09 · 1581 阅读 · 0 评论