![](https://img-blog.csdnimg.cn/aa3fcaae6e30426e91f734cc4e50aef3.png?x-oss-process=image/resize,m_fixed,h_224,w_224)
数据结构与算法
文章平均质量分 95
详细介绍通用算法,比如:二分查找KMP
闻缺陷则喜何志丹
本人拙作《喜缺全书算法册》欢迎指教,可在CSDN下载https://download.csdn.net/download/he_zhidan/88368465
展开
-
VS2019打开《喜缺全书算法册》附带代码的方法兼述单元测试
使用方法一:修改某个封装类,然后运行所有测试用例。看是否有测试用例,没通过。调试没有通过的测试用例。在改测试用例上,单击鼠标右键,在右键菜单中选择“调试”。使用方法二:修改某题的源码,然后运行此类的测试用例。使用方法三:输出日志。Microsoft::VisualStudio::CppUnitTestFramework::Logger::WriteMessage("d"); 选中此测试用例才会显示结果。原创 2024-07-28 07:00:00 · 2567 阅读 · 35 评论 -
【C++BFS算法】2192. 有向无环图中一个节点的所有祖先
求各节点的后代,BFS各节点的层次,层次不是-1,就是后代。求一个节点后代的时间复杂度:O(m) ,m = edges.length,总时间复杂度为:O(nm)。输入:n = 8, edgeList = [[0,3],[0,4],[1,3],[2,4],[2,7],[3,5],[3,6],[3,7],[4,6]]输出:[[],[],[],[0,1],[0,2],[0,1,3],[0,1,2,3,4],[0,1,2,3]]|闻缺陷则喜(喜缺)是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。原创 2024-07-25 07:03:02 · 2594 阅读 · 169 评论 -
【对顶队列】【中位数贪心】【前缀和】3086. 拾起 K 个 1 需要的最少行动次数
给你一个下标从 0 开始的二进制数组 nums,其长度为 n ;另给你一个 正整数 k 以及一个 非负整数 maxChanges 。灵茶山艾府在玩一个游戏,游戏的目标是让灵茶山艾府使用 最少 数量的 行动 次数从 nums 中拾起 k 个 1 。游戏开始时,灵茶山艾府可以选择数组 [0, n - 1] 范围内的任何索引index 站立。如果 nums[index] == 1 ,灵茶山艾府就会拾起一个 1 ,并且 nums[index] 变成0(这 不算 作一次行动)。之后,灵茶山艾府可以执行 任意数量 的原创 2024-03-18 07:00:00 · 1502 阅读 · 59 评论 -
【数学】【组合数学】1830. 使字符串有序的最少操作次数
给你一个字符串 s (下标从 0 开始)。你需要对 s 执行以下操作直到它变为一个有序字符串:找到 最大下标 i ,使得 1原创 2024-03-10 07:00:00 · 628 阅读 · 4 评论 -
【动态规划】【组合数学】【C++算法】920播放列表的数量
你的音乐播放器里有 n 首不同的歌,在旅途中,你计划听 goal 首歌(不一定不同,即,允许歌曲重复)。你将会按如下规则创建播放列表:每首歌 至少播放一次 。原创 2024-01-23 17:00:00 · 916 阅读 · 1 评论 -
【动态规划】【字符串】【状态压缩】943 最短超级串
给定一个字符串数组 words,找到以 words 中每个字符串作为子字符串的最短字符串。如果有多个有效最短字符串满足题目条件,返回其中 任意一个 即可。我们可以假设 words 中没有字符串是 words 中另一个字符串的子字符串。原创 2024-01-24 17:00:00 · 942 阅读 · 0 评论 -
【动态规划】【二分查找】C++算法 466 统计重复个数
定义 str = [s, n] 表示 str 由 n 个字符串 s 连接构成。例如,str == ["abc", 3] =="abcabcabc" 。如果可以从 s2 中删除某些字符使其变为 s1,则称字符串 s1 可以从字符串 s2 获得。例如,根据定义,s1 = "abc" 可以从 s2 = "abdbec" 获得,仅需要删除加粗且用斜体标识的字符。现在给你两个字符串 s1 和 s2 和两个整数 n1 和 n2 。由此构造得到两个字符串,其中 str1 = [s1, n1]、str2 = [s2原创 2024-01-12 15:00:00 · 2015 阅读 · 5 评论 -
C++前缀和算法的应用:1862向下取整数对和
给你一个整数数组 nums ,请你返回所有下标对 0原创 2023-10-22 10:11:12 · 243 阅读 · 0 评论 -
二分查找|双指针:LeetCode:2398.预算内的最多机器人数目
你有 n 个机器人,给你两个下标从 0 开始的整数数组 chargeTimes 和 runningCosts ,两者长度都为 n 。第 i 个机器人充电时间为 chargeTimes[i] 单位时间,花费 runningCosts[i] 单位时间运行。再给你一个整数 budget 。运行 k 个机器人 总开销 是 max(chargeTimes) + k * sum(runningCosts) ,其中 max(chargeTimes) 是这 k 个机器人中最大充电时间,sum(runningCosts)原创 2023-12-10 06:45:00 · 265 阅读 · 2 评论 -
【前缀和]LeetCode1862:向下取整数对和
给你一个整数数组 nums ,请你返回所有下标对 0原创 2023-12-01 06:45:00 · 1307 阅读 · 14 评论 -
【动态规划】【记忆化搜索】【状态压缩】1681. 最小不兼容性
给你一个整数数组 nums 和一个整数 k 。你需要将这个数组划分到 k 个相同大小的子集中,使得同一个子集里面没有两个相同的元素。一个子集的 不兼容性 是该子集里面最大值和最小值的差。请你返回将数组分成 k 个子集后,各子集 不兼容性 的 和 的 最小值 ,如果无法分成分成 k 个子集,返回 -1 。子集的定义是数组中一些数字的集合,对数字顺序没有要求。原创 2024-02-16 17:00:00 · 1242 阅读 · 6 评论 -
【动态规划】【状态压缩】【C++算法】1815 得到新鲜甜甜圈的最多组数
有一个甜甜圈商店,每批次都烤 batchSize 个甜甜圈。这个店铺有个规则,就是在烤一批新的甜甜圈时,之前 所有 甜甜圈都必须已经全部销售完毕。给你一个整数 batchSize 和一个整数数组 groups ,数组中的每个整数都代表一批前来购买甜甜圈的顾客,其中 groups[i] 表示这一批顾客的人数。每一位顾客都恰好只要一个甜甜圈。当有一批顾客来到商店时,他们所有人都必须在下一批顾客来之前购买完甜甜圈。如果一批顾客中第一位顾客得到的甜甜圈不是上一组剩下的,那么这一组人都会很开心。你可以随意安排每批原创 2024-02-17 17:00:00 · 1494 阅读 · 2 评论 -
【单调栈】LeetCode:2818操作使得分最大
给你一个长度为 n 的正整数数组 nums 和一个整数 k 。一开始,你的分数为 1 。你可以进行以下操作至多 k 次,目标是使你的分数最大:选择一个之前没有选过的 非空 子数组 nums[l, ..., r] 。从 nums[l, ..., r] 里面选择一个 质数分数 最高的元素 x 。如果多个元素质数分数相同且最高,选择下标最小的一个。将你的分数乘以 x 。nums[l, ..., r] 表示 nums 中起始下标为 l ,结束下标为 r 的子数组,两个端点都包含。一个整数的 质数分数 等原创 2023-12-23 07:00:00 · 1398 阅读 · 7 评论 -
【数学知识】LCP42: 玩具套圈
「力扣挑战赛」场地外,小力组织了一个套玩具的游戏。所有的玩具摆在平地上,toys[i] 以 [xi,yi,ri] 的形式记录了第 i 个玩具的坐标 (xi,yi) 和半径 ri。小扣试玩了一下,他扔了若干个半径均为 r 的圈,circles[j] 记录了第 j 个圈的坐标 (xj,yj)。套圈的规则如下:若一个玩具被某个圈完整覆盖了(即玩具的任意部分均在圈内或者圈上),则该玩具被套中。若一个玩具被多个圈同时套中,最终仅计算为套中一个玩具请帮助小扣计算,他成功套中了多少玩具。原创 2023-12-15 15:00:00 · 420 阅读 · 8 评论 -
【动态规划】【图论】【C++算法】1301. 最大得分的路径数目
给你一个正方形字符数组 board ,你从数组最右下方的字符 'S' 出发。你的目标是到达数组最左上角的字符 'E' ,数组剩余的部分为数字字符 1, 2, ..., 9 或者障碍 'X'。在每一步移动中,你可以向上、向左或者左上方移动,可以移动的前提是到达的格子没有障碍。一条路径的 「得分」 定义为:路径上所有数字的和。请你返回一个列表,包含两个整数:第一个整数是 「得分」 的最大值,第二个整数是得到最大得分的方案数,请把结果对 10^9 + 7 取余。如果没有任何路径可以到达终点,请返回 [0,原创 2024-02-11 17:00:00 · 1762 阅读 · 3 评论 -
【动态规划】【字符串】【前缀和】1639通过给定词典构造目标字符串的方案数
给你一个字符串列表 words 和一个目标字符串 target 。words 中所有字符串都 长度相同 。你的目标是使用给定的 words 字符串列表按照下述规则构造 target :从左到右依次构造 target 的每一个字符。为了得到 target 第 i 个字符(下标从 0 开始),当 target[i] = words[j][k] 时,你可以使用 words 列表中第 j 个字符串的第 k 个字符。一旦你使用了 words 中第 j 个字符串的第 k 个字符,你不能再使用 words 字符原创 2024-01-31 17:00:00 · 1762 阅读 · 9 评论 -
【动态规划】【滑动窗口】C++算法:3003 执行操作后的最大分割数量
给你一个下标从 0 开始的字符串 s 和一个整数 k。你需要执行以下分割操作,直到字符串 s 变为 空:选择 s 的最长前缀,该前缀最多包含 k 个 不同 字符。删除 这个前缀,并将分割数量加一。如果有剩余字符,它们在 s 中保持原来的顺序。执行操作之 前 ,你可以将 s 中 至多一处 下标的对应字符更改为另一个小写英文字母。在最优选择情形下改变至多一处下标对应字符后,用整数表示并返回操作结束时得到的最大分割数量。原创 2024-01-07 17:41:32 · 1380 阅读 · 2 评论 -
【数学】【记忆化搜索 】【动态规划】964. 表示数字的最少运算符
给定一个正整数 x,我们将会写出一个形如 x (op1) x (op2) x (op3) x ... 的表达式,其中每个运算符 op1,op2,… 可以是加、减、乘、除(+,-,*,或是 /)之一。例如,对于 x = 3,我们可以写出表达式 3 * 3 / 3 + 3 - 3,该式的值为 3 。在写这样的表达式时,我们需要遵守下面的惯例:除运算符(/)返回有理数。任何地方都没有括号。我们使用通常的操作顺序:乘法和除法发生在加法和减法之前。不允许使用一元否定运算符(-)。例如,“x - x” 是一个原创 2024-02-01 17:00:00 · 1814 阅读 · 3 评论 -
C++二分查找算法:793阶乘函数后 K 个零
f(x) 是 x! 末尾是 0 的数量。回想一下 x! = 1 * 2 * 3 * ... * x,且 0! = 1 。例如, f(3) = 0 ,因为 3! = 6 的末尾没有 0 ;而 f(11) = 2 ,因为 11!= 39916800 末端有 2 个 0 。给定 k,找出返回能满足 f(x) = k 的非负整数 x 的数量。原创 2023-11-10 06:45:00 · 215 阅读 · 0 评论 -
C++二分查找视频教程:两数之和
给你一个下标从 1 开始的整数数组 numbers ,该数组已按 非递减顺序排列 ,请你从数组中找出满足相加之和等于目标数 target 的两个数。如果设这两个数分别是 numbers[index1] 和 numbers[index2] ,则 1原创 2023-11-28 06:45:00 · 122 阅读 · 0 评论 -
【前缀和】【分类讨论】【二分查找】2983:回文串重新排列查询
给你一个长度为 偶数 n ,下标从 0 开始的字符串 s 。同时给你一个下标从 0 开始的二维整数数组 queries ,其中 queries[i] = [ai, bi, ci, di] 。对于每个查询 i ,你需要执行以下操作:将下标在范围 0原创 2024-01-02 07:00:00 · 1067 阅读 · 13 评论 -
【多数组合 数学 字符串】2514. 统计同位异构字符串数目
给你一个字符串 s ,它包含一个或者多个单词。单词之间用单个空格 ' ' 隔开。如果字符串 t 中第 i 个单词是 s 中第 i 个单词的一个 排列 ,那么我们称字符串 t 是字符串 s 的同位异构字符串。比方说,"acb dfe" 是 "abc def" 的同位异构字符串,但是 "def cab" 和 "adc bef" 不是。请你返回 s 的同位异构字符串的数目,由于答案可能很大,请你将它对 109 + 7 取余 后返回。原创 2024-05-04 07:00:00 · 976 阅读 · 1 评论 -
【字符串】【 LCP】【C++算法】2573找出对应 LCP 矩阵的字符串
对任一由 n 个小写英文字母组成的字符串 word ,我们可以定义一个 n x n 的矩阵,并满足:lcp[i][j] 等于子字符串 word[i,...,n-1] 和 word[j,...,n-1] 之间的最长公共前缀的长度。给你一个 n x n 的矩阵 lcp 。返回与 lcp 对应的、按字典序最小的字符串 word 。如果不存在这样的字符串,则返回空字符串。对于长度相同的两个字符串 a 和 b ,如果在 a 和 b 不同的第一个位置,字符串 a 的字母在字母表中出现的顺序先于 b 中的对应字母,原创 2024-02-20 17:00:00 · 838 阅读 · 1 评论 -
【动态规划】C++算法:446等差数列划分 II - 子序列
给你一个整数数组 nums ,返回 nums 中所有 等差子序列 的数目。如果一个序列中 至少有三个元素 ,并且任意两个相邻元素之差相同,则称该序列为等差序列。例如,[1, 3, 5, 7, 9]、[7, 7, 7, 7] 和 [3, -1, -5, -9] 都是等差序列。再例如,[1, 1, 2, 5, 7] 不是等差序列。数组中的子序列是从数组中删除一些元素(也可能不删除)得到的一个序列。例如,[2,5,10] 是 [1,2,1,2,4,1,5,10] 的一个子序列。题目数据保证答案是一个原创 2024-01-09 07:00:00 · 1238 阅读 · 6 评论 -
【深度优先搜索】【组合数学】【动态规划】1467.两个盒子中球的颜色数相同的概率
桌面上有 2n 个颜色不完全相同的球,球上的颜色共有 k 种。给你一个大小为 k 的整数数组 balls ,其中 balls[i] 是颜色为 i 的球的数量。所有的球都已经 随机打乱顺序 ,前 n 个球放入第一个盒子,后 n 个球放入另一个盒子(请认真阅读示例 2 的解释部分)。注意:这两个盒子是不同的。例如,两个球颜色分别为 a 和 b,盒子分别为 [] 和 (),那么 [a] (b) 和 [b] (a) 这两种分配方式是不同的(请认真阅读示例的解释部分)。请返回「两个盒子中球的颜色数相同」的情况的原创 2024-01-30 07:00:00 · 1157 阅读 · 5 评论 -
【性能优化】 【回溯】 【字符串】1307. 口算难题
给你一个方程,左边用 words 表示,右边用 result 表示。你需要根据以下规则检查方程是否可解:每个字符都会被解码成一位数字(0 - 9)。每对不同的字符必须映射到不同的数字。每个 words[i] 和 result 都会被解码成一个没有前导零的数字。左侧数字之和(words)等于右侧数字(result)。 如果方程可解,返回 True,否则返回 False。原创 2024-03-28 07:00:00 · 2412 阅读 · 156 评论 -
【状态压缩 动态规划 数论】1799. N 次操作后的最大分数和
给你 nums ,它是一个大小为 2 * n 的正整数数组。你必须对这个数组执行 n 次操作。在第 i 次操作时(操作编号从 1 开始),你需要:选择两个元素 x 和 y 。获得分数 i * gcd(x, y) 。将 x 和 y 从 nums 中删除。请你返回 n 次操作后你能获得的分数和最大为多少。函数 gcd(x, y) 是 x 和 y 的最大公约数。原创 2024-05-07 07:00:00 · 986 阅读 · 9 评论 -
【数位dp】【数论】【动态规划】2999. 统计强大整数的数目
给你三个整数 start ,finish 和 limit 。同时给你一个下标从 0 开始的字符串 s ,表示一个 正 整数。如果一个 正 整数 x 末尾部分是 s (换句话说,s 是 x 的 后缀),且 x 中的每个数位至多是 limit ,那么我们称 x 是 强大的 。请你返回区间 [start..finish] 内强大整数的 总数目 。如果一个字符串 x 是 y 中某个下标开始(包括 0 ),到下标为 y.length - 1 结束的子字符串,那么我们称 x 是 y 的一个后缀。比方说,25 是原创 2024-03-30 17:00:00 · 1025 阅读 · 4 评论 -
[二分查找]LeetCode2009 :使数组连续的最少操作数
给你一个整数数组 nums 。每一次操作中,你可以将 nums 中 任意 一个元素替换成 任意 整数。如果 nums 满足以下条件,那么它是 连续的 :nums 中所有元素都是 互不相同 的。nums 中 最大 元素与 最小 元素的差等于 nums.length - 1 。比方说,nums = [4, 2, 5, 3] 是 连续的 ,但是 nums = [1, 2, 3, 5, 6] 不是连续的 。请你返回使 nums 连续 的 最少 操作次数。原创 2023-12-03 06:45:00 · 185 阅读 · 0 评论 -
【动态规划】【图论】【C++算法】1575统计所有可行路径
给你一个 互不相同 的整数数组,其中 locations[i] 表示第 i 个城市的位置。同时给你 start,finish 和 fuel 分别表示出发城市、目的地城市和你初始拥有的汽油总量每一步中,如果你在城市 i ,你可以选择任意一个城市 j ,满足 j != i 且 0原创 2024-01-29 17:00:00 · 2316 阅读 · 10 评论 -
【调和级数 并集查找】1627. 带阈值的图连通性
有 n 座城市,编号从 1 到 n 。编号为 x 和 y 的两座城市直接连通的前提是: x 和 y 的公因数中,至少有一个 严格大于 某个阈值 threshold 。更正式地说,如果存在整数 z ,且满足以下所有条件,则编号 x 和 y 的城市之间有一条道路:x % z == 0y % z == 0z > threshold给你两个整数 n 和 threshold ,以及一个待查询数组,请你判断每个查询 queries[i] = [ai, bi] 指向的城市 ai 和 bi 是否连通(即,它们之间是原创 2024-05-04 17:00:00 · 849 阅读 · 5 评论 -
【单调栈】LeetCode2334:元素值大于变化阈值的子数组
给你一个整数数组 nums 和一个整数 threshold 。找到长度为 k 的 nums 子数组,满足数组中 每个 元素都 大于 threshold / k 。请你返回满足要求的 任意 子数组的 大小 。如果没有这样的子数组,返回 -1 。子数组 是数组中一段连续非空的元素序列。原创 2023-12-22 07:00:00 · 1803 阅读 · 4 评论 -
【贪心]【字符串】【分类讨论】420 强密码检验器
满足以下条件的密码被认为是强密码:由至少 6 个,至多 20 个字符组成。包含至少 一个小写 字母,至少 一个大写 字母,和至少 一个数字 。不包含连续三个重复字符 (比如 "Baaabb0" 是弱密码, 但是 "Baaba0" 是强密码)。给你一个字符串 password ,返回 将 password 修改到满足强密码条件需要的最少修改步数。如果 password 已经是强密码,则返回 0 。在一步修改操作中,你可以:插入一个字符到 password ,从 password 中删除一个字符,原创 2024-03-27 07:00:00 · 951 阅读 · 9 评论 -
【map】【滑动窗口】【字典树】C++算法:2781最长合法子字符串的长度
给你一个字符串 word 和一个字符串数组 forbidden 。如果一个字符串不包含 forbidden 中的任何字符串,我们称这个字符串是 合法 的。请你返回字符串 word 的一个 最长合法子字符串 的长度。子字符串 指的是一个字符串中一段连续的字符,它可以为空。原创 2023-12-31 17:00:00 · 1097 阅读 · 10 评论 -
【位运算 拆位法 二分】3007. 价值和小于等于 K 的最大数字
给你一个整数 k 和一个整数 x 。整数 num 的价值是由它的二进制表示中,从最低有效位开始,x,2x,3x,以此类推,这些位置上 设置位 的数目来计算。下面的表格包含了如何计算价值的例子。x num Binary Representation Price1 13 000001101 32 13 000001101 12 233 011101001 33 13 000001101 13 362 101101010 2num 的 累加价值 是从 1 到 num 的数字的 总 价值。如果 n原创 2024-04-19 07:00:00 · 1292 阅读 · 10 评论 -
C++算法前缀和的应用:分割数组的最大值的原理、源码及测试用例
分割数组的最大值。原创 2023-10-17 18:53:09 · 1082 阅读 · 8 评论 -
【双指针】【C++算法】1537. 最大得分
你有两个 有序 且数组内元素互不相同的数组 nums1 和 nums2 。一条 合法路径 定义如下:选择数组 nums1 或者 nums2 开始遍历(从下标 0 处开始)。从左到右遍历当前数组。如果你遇到了 nums1 和 nums2 中都存在的值,那么你可以切换路径到另一个数组对应数字处继续遍历(但在合法路径中重复数字只会被统计一次)。得分 定义为合法路径中不同数字的和。请你返回 所有可能 合法路径 中的最大得分。由于答案可能很大,请你将它对 10^9 + 7 取余后返回。原创 2024-02-14 17:00:00 · 1730 阅读 · 2 评论 -
【动态规划】C++算法:115.不同的子序列
给你两个字符串 s 和 t ,统计并返回在 s 的 子序列 中 t 出现的个数,结果需要对 109 + 7 取模。原创 2024-01-05 12:15:00 · 905 阅读 · 2 评论 -
【深度优先】LeetCode1932:合并多棵二叉搜索树
给你 n 个 二叉搜索树的根节点 ,存储在数组 trees 中(下标从 0 开始),对应 n 棵不同的二叉搜索树。trees 中的每棵二叉搜索树 最多有 3 个节点 ,且不存在值相同的两个根节点。在一步操作中,将会完成下述步骤:选择两个 不同的 下标 i 和 j ,要求满足在 trees[i] 中的某个 叶节点 的值等于 trees[j] 的 根节点的值 。用 trees[j] 替换 trees[i] 中的那个叶节点。从 trees 中移除 trees[j] 。如果在执行 n - 1 次操作后,能形原创 2023-12-01 06:45:00 · 236 阅读 · 2 评论 -
【动态规划】【C++算法】1340. 跳跃游戏 V
给你一个整数数组 arr 和一个整数 d 。每一步你可以从下标 i 跳到:i + x ,其中 i + x < arr.length 且 0 < x = 0 且 0 < x arr[j] 且 arr[i] > arr[k] ,其中下标 k 是所有 i 到 j 之间的数字(更正式的,min(i, j) < k < max(i, j))。你可以选择数组的任意下标开始跳跃。请你返回你原创 2024-02-02 07:00:00 · 1040 阅读 · 7 评论