数据结构与算法
文章平均质量分 96
详细介绍通用算法,比如:二分查找KMP
闻缺陷则喜何志丹
本人拙作《闻缺陷则喜算法册》欢迎指教,可在CSDN下载https://download.csdn.net/download/he_zhidan/88368465
展开
-
【动态规划 状态机dp 性能优化】3098. 求出所有子序列的能量和
给你一个长度为 n 的整数数组 nums 和一个 正 整数 k 。一个子序列的 能量 定义为子序列中 任意 两个元素的差值绝对值的 最小值 。请你返回 nums 中长度 等于 k 的 所有 子序列的 能量和 。原创 2024-04-22 07:00:00 · 1833 阅读 · 44 评论 -
动态规划的时间复杂度优化
优化动态规划的时间复杂度,主要有如下几种:原创 2024-02-26 07:00:00 · 4025 阅读 · 164 评论 -
【广度优先搜索】【网格】【割点】1263. 推箱子
「推箱子」是一款风靡全球的益智小游戏,玩家需要将箱子推到仓库中的目标位置。游戏地图用大小为 m x n 的网格 grid 表示,其中每个元素可以是墙、地板或者是箱子。现在你将作为玩家参与游戏,按规则将箱子 'B' 移动到目标位置 'T' :玩家用字符 'S' 表示,只要他在地板上,就可以在网格中向上、下、左、右四个方向移动。地板用字符 '.' 表示,意味着可以自由行走。墙用字符 '#' 表示,意味着障碍物,不能通行。 箱子仅有一个,用字符 'B' 表示。相应地,网格上有一个目标位置 'T'。玩原创 2024-02-22 07:00:00 · 2975 阅读 · 140 评论 -
【深度优先搜索】【树】【有向图】【推荐】685. 冗余连接 II
在本问题中,有根树指满足以下条件的 有向 图。该树只有一个根节点,所有其他节点都是该根节点的后继。该树除了根节点之外的每一个节点都有且只有一个父节点,而根节点没有父节点。输入一个有向图,该图由一个有着 n 个节点(节点值不重复,从 1 到 n)的树及一条附加的有向边构成。附加的边包含在 1 到 n 中的两个不同顶点间,这条附加的边不属于树中已存在的边。结果图是一个以边组成的二维数组 edges 。 每个元素是一对 [ui, vi],用以表示 有向 图中连接顶点 ui 和顶点 vi 的边,其中 ui 是原创 2024-02-19 07:00:00 · 1893 阅读 · 85 评论 -
【数位dp】【动态规划】【状态压缩】【推荐】1012. 至少有 1 位重复的数字
给定正整数 n,返回在 [1, n] 范围内具有 至少 1 位 重复数字的正整数的个数。原创 2024-02-15 07:00:00 · 3318 阅读 · 69 评论 -
【动态规划】【状态压缩】【2次选择】【广度搜索】1494. 并行课程 II
给你一个整数 n 表示某所大学里课程的数目,编号为 1 到 n ,数组 relations 中, relations[i] = [xi, yi] 表示一个先修课的关系,也就是课程 xi 必须在课程 yi 之前上。同时你还有一个整数 k 。在一个学期中,你 最多 可以同时上 k 门课,前提是这些课的先修课在之前的学期里已经上过了。请你返回上完所有课最少需要多少个学期。题目保证一定存在一种上完所有课的方式。原创 2024-02-05 07:00:00 · 2174 阅读 · 66 评论 -
【动态规划】【字符串】【行程码】1531. 压缩字符串
行程长度编码 是一种常用的字符串压缩方法,它将连续的相同字符(重复 2 次或更多次)替换为字符和表示字符计数的数字(行程长度)。例如,用此方法压缩字符串 "aabccc" ,将 "aa" 替换为 "a2" ,"ccc" 替换为` "c3" 。因此压缩后的字符串变为 "a2bc3" 。注意,本问题中,压缩时没有在单个字符后附加计数 '1' 。给你一个字符串 s 和一个整数 k 。你需要从字符串 s 中删除最多 k 个字符,以使 s 的行程长度编码长度最小。请你返回删除最多 k 个字符后,s 行程长度编码原创 2024-01-29 07:00:00 · 2120 阅读 · 137 评论 -
【动态规划】【广度优先搜索】【状态压缩】847 访问所有节点的最短路径
存在一个由 n 个节点组成的无向连通图,图中的节点按从 0 到 n - 1 编号。给你一个数组 graph 表示这个图。其中,graph[i] 是一个列表,由所有与节点 i 直接相连的节点组成。返回能够访问所有节点的最短路径的长度。你可以在任一节点开始和停止,也可以多次重访节点,并且可以重用边。原创 2024-01-22 07:00:00 · 2922 阅读 · 130 评论 -
【动态规划】【数学】【C++算法】18赛车
你的赛车可以从位置 0 开始,并且速度为 +1 ,在一条无限长的数轴上行驶。赛车也可以向负方向行驶。赛车可以按照由加速指令 'A' 和倒车指令 'R' 组成的指令序列自动行驶。当收到指令 'A' 时,赛车这样行驶:position += speedspeed *= 2当收到指令 'R' 时,赛车这样行驶:如果速度为正数,那么speed = -1否则 speed = 1当前所处位置不变。例如,在执行指令 "AAR" 后,赛车位置变化为 0 --> 1 --> 3 --> 3 ,速度变化为 1原创 2024-01-18 07:00:00 · 3330 阅读 · 140 评论 -
【动态规划】【矩阵快速幂】【滚动向量】C++算法552. 学生出勤记录 II
可以用字符串表示一个学生的出勤记录,其中的每个字符用来标记当天的出勤情况(缺勤、迟到、到场)。记录中只含下面三种字符:'A':Absent,缺勤'L':Late,迟到'P':Present,到场如果学生能够 同时 满足下面两个条件,则可以获得出勤奖励:按 总出勤 计,学生缺勤('A')严格 少于两天。学生 不会 存在 连续 3 天或 连续 3 天以上的迟到('L')记录。给你一个整数 n ,表示出勤记录的长度(次数)。请你返回记录长度为 n 时,可能获得出勤奖励的记录情况 数量 。答案可能很大原创 2024-01-14 07:00:00 · 1177 阅读 · 8 评论 -
【矩阵快速幂】封装类及测试用例及样例
通俗的说,就是矩阵的乘方。原创 2024-01-15 07:00:00 · 1639 阅读 · 130 评论 -
【动态规划】C++算法312 戳气球
有 n 个气球,编号为0 到 n - 1,每个气球上都标有一个数字,这些数字存在数组 nums 中。现在要求你戳破所有的气球。戳破第 i 个气球,你可以获得 nums[i - 1] * nums[i] * nums[i + 1] 枚硬币。 这里的 i - 1 和 i + 1 代表和 i 相邻的两个气球的序号。如果 i - 1或 i + 1 超出了数组的边界,那么就当它是一个数字为 1 的气球。求所能获得硬币的最大数量。原创 2024-01-08 07:00:00 · 3217 阅读 · 112 评论 -
【动态规划】【字符串】C++算法:10正则表达式匹配
给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 '.' 和 '*' 的正则表达式匹配。'.' 匹配任意单个字符'*' 匹配零个或多个前面的那一个元素所谓匹配,是要涵盖 整个 字符串 s的,而不是部分字符串。原创 2024-01-01 07:00:00 · 2927 阅读 · 84 评论 -
动态规划 多源路径 字典树 LeetCode2977:转换字符串的最小成本
给你两个下标从 0 开始的字符串 source 和 target ,它们的长度均为 n 并且由 小写 英文字母组成。另给你两个下标从 0 开始的字符串数组 original 和 changed ,以及一个整数数组 cost ,其中 cost[i] 代表将字符串 original[i] 更改为字符串 changed[i] 的成本。你从字符串 source 开始。在一次操作中,如果 存在 任意 下标 j 满足 cost[j] == z 、original[j] == x 以及 changed[j] ==原创 2023-12-28 07:00:00 · 3617 阅读 · 99 评论 -
map|动态规划|单调栈|975:奇偶跳
给定一个整数数组 A,你可以从某一起始索引出发,跳跃一定次数。在你跳跃的过程中,第 1、3、5... 次跳跃称为奇数跳跃,而第 2、4、6... 次跳跃称为偶数跳跃。你可以按以下方式从索引 i 向后跳转到索引 j(其中 i < j):在进行奇数跳跃时(如,第 1,3,5... 次跳跃),你将会跳到索引 j,使得 A[i]原创 2023-12-21 07:00:00 · 4731 阅读 · 92 评论 -
【动态规划】【广度优先搜索】【逆向思考】【单调向量】2617 网格图中最少访问的格子数
给你一个下标从 0 开始的 m x n 整数矩阵 grid 。你一开始的位置在 左上角 格子 (0, 0) 。当你在格子 (i, j) 的时候,你可以移动到以下格子之一:满足 j < k原创 2023-12-15 07:00:00 · 3774 阅读 · 97 评论 -
【动态规划】【广度优先】LeetCode2258:逃离火灾
给你一个下标从 0 开始大小为 m x n 的二维整数数组 grid ,它表示一个网格图。每个格子为下面 3 个值之一:0 表示草地。1 表示着火的格子。2 表示一座墙,你跟火都不能通过这个格子。一开始你在最左上角的格子 (0, 0) ,你想要到达最右下角的安全屋格子 (m - 1, n - 1) 。每一分钟,你可以移动到 相邻 的草地格子。每次你移动 之后 ,着火的格子会扩散到所有不是墙的 相邻 格子。请你返回你在初始位置可以停留的 最多 分钟数,且停留完这段时间后你还能安全到达安全屋。如果无法原创 2023-12-10 09:21:31 · 4192 阅读 · 150 评论 -
【二分查找】【位运算】2354.优质数对的数目
给你一个下标从 0 开始的正整数数组 nums 和一个正整数 k 。如果满足下述条件,则数对 (num1, num2) 是 优质数对 :num1 和 num2 都 在数组 nums 中存在。num1 OR num2 和 num1 AND num2 的二进制表示中值为 1 的位数之和大于等于 k ,其中 OR 是按位 或 操作,而 AND 是按位 与 操作。返回 不同 优质数对的数目。如果 a != c 或者 b != d ,则认为 (a, b) 和 (c, d) 是不同的两个数对。例如,(1, 2原创 2023-12-09 06:45:00 · 1016 阅读 · 0 评论 -
【贪心算法】LeetCode2071:你可以安排的最多任务数目
给你 n 个任务和 m 个工人。每个任务需要一定的力量值才能完成,需要的力量值保存在下标从 0 开始的整数数组 tasks 中,第 i 个任务需要 tasks[i] 的力量才能完成。每个工人的力量值保存在下标从 0 开始的整数数组 workers 中,第 j 个工人的力量值为 workers[j] 。每个工人只能完成 一个 任务,且力量值需要 大于等于 该任务的力量要求值(即 workers[j] >= tasks[i] )。除此以外,你还有 pills 个神奇药丸,可以给 一个工人的力量值 增加 str原创 2023-12-07 07:00:00 · 1941 阅读 · 119 评论 -
[二分查找]LeetCode2040:两个有序数组的第 K 小乘积
给你两个 从小到大排好序 且下标从 0 开始的整数数组 nums1 和 nums2 以及一个整数 k ,请你返回第 k (从 1 开始编号)小的 nums1[i] * nums2[j] 的乘积,其中 0原创 2023-12-04 07:00:00 · 1555 阅读 · 109 评论 -
【广度优先】【模拟】838推多米诺
n 张多米诺骨牌排成一行,将每张多米诺骨牌垂直竖立。在开始时,同时把一些多米诺骨牌向左或向右推。每过一秒,倒向左边的多米诺骨牌会推动其左侧相邻的多米诺骨牌。同样地,倒向右边的多米诺骨牌也会推动竖立在其右侧的相邻多米诺骨牌。如果一张垂直竖立的多米诺骨牌的两侧同时有多米诺骨牌倒下时,由于受力平衡, 该骨牌仍然保持不变。就这个问题而言,我们会认为一张正在倒下的多米诺骨牌不会对其它正在倒下或已经倒下的多米诺骨牌施加额外的力。给你一个字符串 dominoes 表示这一行多米诺骨牌的初始状态,其中:domin原创 2023-11-27 11:30:00 · 1696 阅读 · 106 评论 -
【二分算法】1521:找到最接近目标值的函数值
Winston 构造了一个如上所示的函数 func 。他有一个整数数组 arr 和一个整数 target ,他想找到让 |func(arr, l, r) - target| 最小的 l 和 r 。请你返回 |func(arr, l, r) - target| 的最小值。请注意, func 的输入参数 l 和 r 需要满足 0原创 2023-11-21 06:45:00 · 303 阅读 · 0 评论 -
【二分查找】1439:有序矩阵中的第 k 个最小数组和
给你一个 m * n 的矩阵 mat,以及一个整数 k ,矩阵中的每一行都以非递减的顺序排列。你可以从每一行中选出 1 个元素形成一个数组。返回所有可能数组中的第 k 个 最小 数组和。原创 2023-11-20 07:00:00 · 1533 阅读 · 103 评论 -
【二分算法】1187:使数组严格递增
给你两个整数数组 arr1 和 arr2,返回使 arr1 严格递增所需要的最小「操作」数(可能为 0)。每一步「操作」中,你可以分别从 arr1 和 arr2 中各选出一个索引,分别为 i 和 j,0原创 2023-11-17 07:00:00 · 445 阅读 · 5 评论 -
一题三解(暴力、二分查找算法、单指针):887鸡蛋掉落
给你 k 枚相同的鸡蛋,并可以使用一栋从第 1 层到第 n 层共有 n 层楼的建筑。已知存在楼层 f ,满足 0原创 2023-11-11 07:00:00 · 509 阅读 · 28 评论 -
【二分算法】:778水位上升的泳池中游泳
在一个 n x n 的整数矩阵 grid 中,每一个方格的值 grid[i][j] 表示位置 (i, j) 的平台高度。当开始下雨时,在时间为 t 时,水池中的水位为 t 。你可以从一个平台游向四周相邻的任意一个平台,但是前提是此时水位必须同时淹没这两个平台。假定你可以瞬间移动无限距离,也就是默认在方格内部游动是不耗时的。当然,在你游泳的时候你必须待在坐标方格里面。你从坐标方格的左上平台 (0,0) 出发。返回 你到达坐标方格的右下平台 (n-1, n-1) 所需的最少时间 。原创 2023-11-09 07:00:00 · 1286 阅读 · 11 评论 -
C++深度优先搜索(DFS)算法的应用:2791树中可以形成回文的路径数
给你一棵 树(即,一个连通、无向且无环的图),根 节点为 0 ,由编号从 0 到 n - 1 的 n 个节点组成。这棵树用一个长度为 n 、下标从 0 开始的数组 parent 表示,其中 parent[i] 为节点 i 的父节点,由于节点 0 为根节点,所以 parent[0] == -1 。另给你一个长度为 n 的字符串 s ,其中 s[i] 是分配给 i 和 parent[i] 之间的边的字符。s[0] 可以忽略。找出满足 u < v ,且从 u 到 v 的路径上分配的字符可以 重新排列 形成原创 2023-11-08 07:00:00 · 1344 阅读 · 105 评论 -
C++前缀和算法的应用:2528最大化城市的最小供电站数目
给你一个下标从 0 开始长度为 n 的整数数组 stations ,其中 stations[i] 表示第 i 座城市的供电站数目。每个供电站可以在一定 范围 内给所有城市提供电力。换句话说,如果给定的范围是 r ,在城市 i 处的供电站可以给所有满足 |i - j|原创 2023-11-06 07:00:00 · 3230 阅读 · 100 评论 -
C++二分查找算法的应用:2790长度递增组的最大数目
给你一个下标从 0 开始、长度为 n 的数组 usageLimits 。你的任务是使用从 0 到 n - 1 的数字创建若干组,并确保每个数字 i 在 所有组 中使用的次数总共不超过 usageLimits[i] 次。此外,还必须满足以下条件:每个组必须由 不同 的数字组成,也就是说,单个组内不能存在重复的数字。每个组(除了第一个)的长度必须 严格大于 前一个组。在满足所有条件的情况下,以整数形式返回可以创建的最大组数。原创 2023-11-04 07:00:00 · 258 阅读 · 20 评论 -
C++二分查找算法的应用:354俄罗斯套娃信封问题
给你一个二维整数数组 envelopes ,其中 envelopes[i] = [wi, hi] ,表示第 i 个信封的宽度和高度。当另一个信封的宽度和高度都比这个信封大的时候,这个信封就可以放进另一个信封里,如同俄罗斯套娃一样。请计算 最多能有多少个 信封能组成一组“俄罗斯套娃”信封(即可以把一个信封放到另一个信封里面)。注意:不允许旋转信封。原创 2023-11-02 18:12:06 · 323 阅读 · 8 评论 -
C++二分查找算法的应用:352将数据流变为多个不相交区间
给你一个由非负整数 a1, a2, ..., an 组成的数据流输入,请你将到目前为止看到的数字总结为不相交的区间列表。实现 SummaryRanges 类:SummaryRanges() 使用一个空数据流初始化对象。void addNum(int val) 向数据流中加入整数 val 。int[][] getIntervals() 以不相交区间 [starti, endi] 的列表形式返回对数据流中整数的总结。原创 2023-11-03 07:00:00 · 159 阅读 · 0 评论 -
C++排序、前缀和算法的应用:2681英雄的力量
给你一个下标从 0 开始的整数数组 nums ,它表示英雄的能力值。如果我们选出一部分英雄,这组英雄的 力量 定义为:i0 ,i1 ,... ik 表示这组英雄在数组中的下标。那么这组英雄的力量为 max(nums[i0],nums[i1] ... nums[ik])2 * min(nums[i0],nums[i1] ... nums[ik]) 。请你返回所有可能的 非空 英雄组的 力量 之和。由于答案可能非常大,请你将结果对 109 + 7 取余。原创 2023-11-02 07:00:00 · 249 阅读 · 11 评论 -
C++前缀和算法的应用:47统计上升四元组
C++前缀和算法的应用:统计上升四元组。原创 2023-11-01 07:00:00 · 1424 阅读 · 112 评论 -
C++前缀和算法的应用:2106摘水果
给你一个二维整数数组 fruits ,其中 fruits[i] = [positioni, amounti] 表示共有 amounti 个水果放置在 positioni 上。有效学习:明确的目标 及时的反馈 拉伸区(难度合适),可以先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。输入:fruits = [[2,8],[6,3],[8,6]], startPos = 5, k = 4。|闻缺陷则喜是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。二,先左移,后右移。原创 2023-10-26 07:15:00 · 508 阅读 · 24 评论 -
C++前缀和算法的应用:1872石头游戏 VIII
dp[i]表示剩余i个石头时,(先手方分数-后手方分数)的最大值。计算dp[i]时,假定移除石头后,还剩j个,也就是移除m_c-j个。cur = stones[0,m_c-j)个石头的价值和 - dp[j]。Alice 和 Bob 的 分数之差 为 (Alice 的分数 - Bob 的分数)。有效学习:明确的目标 及时的反馈 拉伸区(难度合适),可以先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。//计算dp[i]时,假定移除石头后,还剩j个,也就是移除m_c-j个。原创 2023-10-24 12:18:14 · 2249 阅读 · 78 评论 -
【动态规划】【字符串】【回文】:2911得到 K 个半回文串的最少修改次数
得到 K 个半回文串的最少修改次数给你一个字符串 s 和一个整数 k ,请你将 s 分成 k 个 子字符串 ,使得每个 子字符串 变成 半回文串 需要修改的字符数目最少。请你返回一个整数,表示需要修改的 最少 字符数目。注意:如果一个字符串从左往右和从右往左读是一样的,那么它是一个 回文串 。如果长度为 len 的字符串存在一个满足 1原创 2023-10-24 07:15:00 · 182 阅读 · 2 评论 -
【前缀和】【动态规划】:1000合并石头的最低成本
C++前缀和算法:合并石头的最低成本原理、源码及测试用例。原创 2023-10-21 10:40:43 · 379 阅读 · 4 评论 -
【动态规划】【前缀和】:903DI序列的有效排列
dp[i][j],表示前i+1个数已经处理,未处理的数中共有j个数大于strRes[i]。下降类似,小于strRes[i]的数,可以计算出来:总数-已经处理的数-未处理的数中大于res[i]=n-(i+1)-j。注意:各位数各不相等,所以已经处理的数(如:res[i])是不会在出现的,所以未处理的数,需要考虑大于和小于,不需要考虑等于。有效学习:明确的目标 及时的反馈 拉伸区(难度合适),可以先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。{//j是小于strRes[i]的数目。原创 2023-10-20 12:11:27 · 1527 阅读 · 62 评论 -
时间复杂度O(40n*n)的C++算法:2699修改图中的边权
1.12.1. 题目给你一个 n 个节点的 无向带权连通 图,节点编号为 0 到 n - 1 ,再给你一个整数数组 edges ,其中 edges[i] = [ai, bi, wi] 表示节点 ai 和 bi 之间有一条边权为 wi 的边。部分边的边权为 -1(wi = -1),其他边的边权都为 正 数(wi > 0)。原创 2023-10-14 12:03:22 · 377 阅读 · 19 评论 -
C++算法:2876有向图计数优化版原理及实现
如果ret[cur]不为-1,说明cur已经处理。如果cur是环上一点,那说明整个环已经处理,返回-1;如果cur,不是环上一点,也返回-1。如果用vector记录PreNO,则需要在for循环外初始化,如果for循环内初始化,则时间复杂度变为O(n*n)。O(n),任意端点,dfs最多执行两次,一次是主动执行,一次是作为出边被执行。cur是当前dfs的节点,next为edges[cur]。不需要拓扑排序,也不需要并集查找,直接dfs了。dfs(next)返回非-1。找到环尾,没找到环首。原创 2023-10-02 16:44:06 · 261 阅读 · 2 评论