- 博客(500)
- 资源 (10)
- 收藏
- 关注
原创 区间DP 模板总结(递推版 / 记忆化搜索版通用伪代码)
区间 DP(interval DP)的核心,就是“状态 = 一个区间”,“转移 = 把区间拆成左右两个子区间再合并结果”。下面用模板化的方式讲一遍:什么时候想到区间 DP、怎么设计状态与转移,以及常见两种代码写法(递推版 / 记忆化搜索版伪代码)。。
2026-01-03 03:06:28
659
原创 区间 DP(Interval DP)全解析:从原理到实战模板
在一维序列上,用dpijdp[i][j]dpij表示区间ij[i, j]ij的最优结果(或代价),并从更小的区间推出更大的区间。区间 DP 是「序列型 DP」的一个重要分支,核心关注的是区间之间的依赖与合并方式。dpij区间ij的最优结果/代价dp[i][j] = \text{区间 } [i, j] \text{ 的最优结果/代价}dpij区间ij的最优结果代价根据题意不同,可能是最小值、最大值、布尔值等。dpijmin。
2026-01-03 02:06:07
470
原创 动态规划DP 自我提问模板
动态规划的本质是"记忆化递归 + 最优子结构",但很多时候我们会在定义状态、推导转移方程时感到困惑。dp[i][j] 定义:明确每个状态代表什么默认值:初始化的边界条件外部遍历:如何遍历整个状态空间choice:在每个状态下有哪些选择(如果适用)cost:每个选择的代价(如果适用)转移条件:什么情况下进行状态转移转移方程:如何从子问题推导到当前问题返回值:最终答案在状态空间的哪个位置dp 和 grid 大小相同,dp[i][j] 表示对应走到 grid[i][j] 的最小sum。
2026-01-01 23:37:15
995
原创 一维 DP 通用思路与模板(计数、背包、股票买卖)
明确 i 的含义:第 i 个元素、前 i 个数、容量为 i、金额 i 等。明确 dp[i] 存什么:最大值 / 最小值 / 方案数 / 布尔(能否到达)。0/1 背包(每件最多一次):容量要倒序防止在同一轮中重复使用同一个物品。完全背包(可以无限次):容量要正序刻意利用“本轮已更新的 dp[j - w]”来表示已经用过当前物品,再多用一次。csdn+1计数 / 组合型问题时,也遵循同样的思路,只是把 max 换成 +=。hold[i]:第 i 天结束时,手里持有一股时的最大利润。
2025-12-26 07:19:47
641
原创 动态规划从 0 到 1:概念、思路、伪代码与常见疑问
很多 DP 原始写法会开一个二维表 dp[n][m],空间是 O(nm)。dp[i][j] 只用到了 dp[i-1][…] 那一行;对更早的行 0…i-2 根本不再需要。这时可以只保留"上一行"和"当前行",甚至只用一维数组,在遍历时控制更新顺序,让同一个数组一会儿代表"旧的一行",一会儿变成"新的一行"。这个"只保留少数几行 / 一维数组,并不断让它们代表不同阶段"的技巧,就叫滚动数组。目的是:把空间从 O(nm) 降到 O(m) 甚至 O(1),称为"空间优化 / 降空间"。
2025-12-25 23:31:26
730
原创 堆与优先队列:从直觉到模板的完整指南
因为要保证树仍然是完全二叉树最右下的叶子正好对应数组最后一个元素;删除这个叶子不会让中间出现“洞”;想删的是堆顶,就把最后一个元素搬到根,再删掉最后一格,然后自上而下siftDown恢复堆性。[11][12]
2025-12-22 05:35:54
784
原创 面向入门者的 Binary Search(二分查找)小结
含义完全一样(right - left) 是当前区间的长度减一。(right - left) // 2 取的是长度的一半(向下取整)。left + 上面这半段,就是"从 left 起往右走一半"的位置,也就是中点。例:left = 2, right = 6,长度 6 - 2 + 1 = 5;right - left = 4,一半是 2,所以 mid = 2 + 2 = 4,刚好是中间。避免溢出风险。
2025-12-12 06:51:09
586
原创 分治算法(Divide & Conquer)通用思路与伪代码模板
分治(Divide & Conquer),直译就是"分而治之":把一个规模较大的问题拆成若干个规模更小、形式相同的子问题,分别解决这些子问题后,再把它们的解合并,得到原问题的解。Divide(分):拆分问题Conquer(治):递归求解子问题Combine(合):合并子问题的解原问题可以拆分成若干个规模更小但结构相同的子问题。子问题之间相对独立,也就是彼此之间关联不太大。有一个明确的"最小规模",当规模足够小时,可以不用再拆,直接解决。能设计出一个高效的合并步骤。
2025-12-11 04:42:06
820
原创 图遍历里“要不要回溯“,关键在于:visited 是全局约束还是“当前这条路径“的约束
图遍历里“要不要回溯”,关键在于:visited 是全局约束还是“当前这条路径”的约束。。
2025-12-10 11:45:13
646
原创 组合问题:为什么用start避免重复
start的作用保证每次只从当前数字后面选避免选到前面的数字因此 [1,2] 会生成,但 [2,1] 不会生成记忆组合:顺序无关 → 用start保证递增 → 避免重复排列:顺序相关 → 用visited避免重用 → 允许任意顺序这就是为什么组合用start,而全排列用visited!
2025-12-09 04:17:05
313
原创 一文搞懂通用回溯思想与伪代码模板
回溯算法是一种通用的搜索方法,通过递归在决策树上进行深度优先搜索。其核心在于:做选择→递归探索→撤销选择,并配合剪枝优化。算法框架包含三个要素:当前路径、可选列表和终止条件。实际应用中,根据问题类型采用不同方式控制选择列表,如组合问题用下标控制、排列问题用标记数组、棋盘问题用合法动作。一维数组通过递归深度和选择顺序形成隐式决策树结构。这种模板化方法能高效解决排列、组合、子集等各类搜索问题。
2025-12-07 04:06:28
687
原创 无权图最短路:为什么用 BFS(附伪代码与 DFS 对比)
顶点部分每个顶点最多入队一次、出队一次,因此与顶点相关的操作是 O(V)。边部分有向图:每条边 (u,v) 只出现在 Adj[u] 中一次,而 u 在 BFS 中只会出队一次,所以这条边只被枚举一次。无向图:每条无向边 {u,v} 会被存为两条有向边 (u -> v) 和 (v -> u),枚举时各被访问一次,总共两次。因此所有边被枚举的总次数与 E 同阶,总时间复杂度为OVEO(V + E)OVEBFS 是天然合适的算法,复杂度 O(V+E),实现简单;普通 DFS。
2025-12-04 11:37:40
1216
原创 如何识别图论问题:从关键词到思维模式
判断"这是图"的关键,是从题目里读出"对象 + 关系/连接",而且这些关系会一层层传递、形成路径或环。可以刻意练一个"图模式识别"的习惯。
2025-12-03 11:30:30
236
原创 图的存储结构:邻接矩阵与邻接表(C 风格伪代码+应用)
1000x3f3f3f3f// 可选:用于带权图时表示"无穷大/无边"int vexnum;// 顶点数int arcnum;// 边数// 顶点信息,比如 'A','B','C'...// 邻接矩阵:无权图用 0/1,有权图用权值} MGraph;含义小结vexs[i]:编号为 i 的顶点的信息(这里用 char 简化)。arcs[i][j]0表示"没有边",1表示"有边";0或INF表示"无边",正数表示边权。// 这条边指向的顶点编号(下标)
2025-12-03 04:24:21
1055
原创 ut_hash 使用指南:从入门到精通
ut_hash是一个纯宏实现的C语言哈希表库,具有以下特点: 使用简单,只需包含头文件即可 支持任意结构体作为哈希节点 提供灵活多样的key类型支持 包含完整的哈希表操作功能 基本用法包括: 在结构体中添加UT_hash_handle字段 定义并初始化表头指针 使用HASH_ADD系列宏插入元素 使用HASH_FIND系列宏查找元素 使用HASH_DEL删除元素 通过HASH_ITER安全遍历 该库特别适合需要轻量级哈希表的C语言项目,避免了额外的库依赖,同时提供了丰富的功能接口。使用时需注意内存管理需要手
2025-12-03 01:13:43
698
原创 Flood Fill 算法完全指南:从原理到应用
Flood Fill 是一个在二维网格(图像、棋盘、地图)上做「连通区域填充」的经典算法。它从一个或多个起点出发,把所有与起点连通、且满足某个条件的格子找出来,并统一做某种操作(比如改颜色、打标记)。最常见的类比就是画图软件里的「油漆桶」工具:在一块蓝色区域上点一下,这块区域中所有与点击点连通的蓝色像素都会被一次性填充成新颜色,这背后的逻辑就是 Flood Fill。BFS 的特点是「一圈一圈扩散」(按距离一层层推进),逻辑和 DFS 一样,只是实现细节不同。
2025-12-02 23:16:56
952
原创 图遍历基础:DFS、BFS 与连通性
在很多算法题和工程场景里,图是最常见的抽象之一:点表示实体,边表示关系,比如社交网络里的用户与关注、地图中的城市与道路等。要分析一张图,首先要能「遍历」它——从某个点出发,把和它连在一起的点系统地走一遍,这就是 DFS 和 BFS 的用武之地。。
2025-12-02 06:47:03
1208
原创 二叉树的 DFS 和 BFS 遍历完全指南
在二叉树上,绝大多数遍历、搜索、路径类题目,都可以归结为「深度优先搜索(DFS)」或「广度优先搜索(BFS)」。二叉树结构简单,非常适合作为入门载体,搞懂这里的 DFS / BFS,再推广到图、网格迷宫都不难。
2025-12-02 06:27:10
744
原创 直观理解三种遍历:preorder / inorder / postorder
在构造二叉树的题里,最常见的三种遍历是 preorder(先序)、inorder(中序)和 postorder(后序)。它们本质上都是 DFS,只是“在什么时候访问根节点”不一样:preorder 是根在前,inorder 是根在中间,postorder 是根在最后。具体来说:一个很容易产生的误区是:“postorder 是不是就是 preorder 反过来?”答案是否定的。只有在非常特殊的结构(例如每个节点只有一个孩子,整棵树退化成一条链)时,preorder 反过来看起来会和 postorder 很像,
2025-11-28 04:48:23
1060
原创 技术积累与总结
该文档包含技术博客和开源代码资源。博客地址为CSDN个人主页,内容未详述。代码部分包含三个GitHub仓库:Linux内核注释项目、面试经验总结以及NVIDIA内核调试工具。这些资源涵盖了操作系统内核研究、求职准备和GPU调试等专业技术领域,适合开发者学习和参考。所有链接均可直接访问相应内容。
2025-11-20 03:20:15
134
原创 LeetCode 76:Minimum Window Substring 题解与滑动窗口思维详解
题目要求找出字符串 s 中包含字符串 t 所有字符的最短子串。使用滑动窗口算法,通过双指针动态调整窗口范围,统计字符频次来满足条件。具体步骤包括: 统计字符需求:记录 t 中每个字符的出现次数。 滑动窗口扩展:右指针遍历 s,将字符加入窗口并更新计数。 窗口收缩优化:当窗口满足条件时,左指针右移以寻找更短的合法子串。 结果更新:记录最短子串的起始位置和长度。 最终返回满足条件的最短子串,若不存在则返回空字符串。时间复杂度为 O(m + n),空间复杂度为 O(1)(使用固定大小的数组)或 O(k)(使用哈希
2026-05-02 03:46:59
386
原创 LeetCode 30:Substring with Concatenation of All Words 题解(含 C 语言 uthash 实现)
摘要 本文分析了LeetCode 30题的解题思路,提出了一种基于滑动窗口的高效算法。题目要求在给定字符串中找到所有能由指定单词数组拼接而成的子串起始位置。核心解法分为四步:1) 预处理单词词频;2) 按单词长度分组枚举起点;3) 将字符串抽象为单词数组;4) 对每组起点应用滑动窗口算法。该方法充分利用单词长度相同的条件,通过哈希表统计词频,将时间复杂度优化至O(n*m),其中n为字符串长度,m为单词长度。文中还详细讨论了C语言实现中uthash的使用技巧和边界条件处理。
2026-05-01 22:34:43
449
原创 LeetCode 42:接雨水 —— 从“矩形法”到双指针的完整思考过程
本文分析了LeetCode 42题"接雨水"的双指针解法。通过非负整数数组表示柱子高度,计算下雨后能接的雨水量。关键公式是每个位置的水量由左右最高柱子的较小值决定。双指针法通过维护leftMax和rightMax两个变量,在O(n)时间、O(1)空间内完成计算。核心思想是每次移动较矮一侧的指针,确保当前格子的水量能被准确计算。文中给出了伪代码和C语言实现,并解释了从直观到抽象的思考过程。
2026-05-01 06:05:45
598
原创 LeetCode 68. Text Justification 题解:贪心与实现细节
LeetCode 68题要求实现文本两端对齐功能。给定单词数组和行宽,需将单词按行排版,每行刚好达到指定宽度。关键规则包括:采用贪心策略每行尽可能多放单词;中间行需两端对齐,多余空格平均分配(左多右少);最后一行左对齐;单单词行也左对齐。实现分为两步:1) 用贪心算法划分每行单词范围;2) 根据行类型(中间行/最后一行/单单词行)采用不同空格分配策略。C语言实现时可采用预填空格再写入单词的技巧简化操作。本题难点在于处理各种边界条件和精确的空格计算。
2026-05-01 03:21:06
333
原创 LeetCode 135. Candy:从直觉到最优解的完整推导
这篇文章记录了解决LeetCode 135「Candy」问题的完整思考过程。最初尝试仅从左到右扫描的简单解法存在缺陷,未能考虑右侧邻居的约束。通过分析反例,发现需要双向扫描:首先从左到右确保每个孩子比左边评分高的邻居多得糖,再从右到左处理右侧邻居的约束。最终方案采用两遍扫描和动态调整糖果分配的策略,时间复杂度O(n),空间复杂度O(n)。文章详细阐述了算法设计思路,包括边界情况处理和复杂度分析,并提供了通过测试的C语言实现代码。整个过程展示了从错误直觉到标准解法的完整演进路径。
2026-04-30 23:20:16
540
原创 LeetCode 149: Max Points on a Line - 解题思路详解
这篇文章详细解析了LeetCode第149题"Max Points on a Line"的解题思路。核心方法是固定一个基准点,计算与其他点的斜率,使用最简分数形式(dy,dx)作为哈希键来统计共线点数。重点解决了浮点精度问题(通过GCD约分)和特殊情况处理(垂直线/水平线)。文章还介绍了GCD算法原理和实现,以及C语言中uthash库的使用建议。时间复杂度为O(n²),适用于最多300个点的情况。通过系统化的数学分析和代码实现指导,帮助读者掌握判断多点共线的有效方法。
2026-04-30 10:26:46
387
原创 LeetCode 50. Pow(x, n):从 O(n) 到 O(log n) 的快速幂彻底搞懂
快速幂算法通过将指数n分解为2的幂次和,实现高效计算x^n。核心思想是利用x^(2^k)的递推性质,每次将指数折半处理。具体步骤:1) 处理n=0和负指数情况;2) 初始化result=1,base=x;3) 循环处理指数e=|n|,若e为奇数则result乘当前base,随后base平方并e折半;4) 最终根据n的符号返回结果。该算法将时间复杂度从O(n)降至O(logn),适合大指数计算。关键在于理解"幂积木"的生成与选择过程,而非简单循环相乘。
2026-04-30 05:14:14
351
原创 LeetCode动态规划经典题:Unique Paths 网格路径计数详解
在一个 m×n 的网格上,有一个机器人从左上角 (0,0) 出发,只能向右或向下移动一步。leetcode目标是到达右下角 (m−1,n−1),要求计算一共有多少条不同的路径。leetcode约束:1≤m,n≤100,测试数据保证答案不超过 2×10^9。leetcode。
2026-01-07 23:20:04
1079
原创 LeetCode 172. Factorial Trailing Zeroes 题解
LeetCode 172. Factorial Trailing Zeroes:给定一个整数 n,返回 n!中尾随零(结尾连续的 0)的个数。leetcoden!Follow up:是否可以在对数时间复杂度内求解。leetcode。
2026-01-07 23:09:32
849
原创 动态规划解决 Decode Ways 问题:从理解到实现
基础状态:dp[0] = 1,表示空字符串有 1 种"什么都不选"的解码方式,这是后续转移的起点。取出两位数:digit_2 = (s[i-2]-‘0’) * 10 + (s[i-1]-‘0’)。比如 “12” 可以解码为 “AB”(1,2)或 “L”(12),所以答案是 2。但像 “06” 这种因为有前导 0,不能解码成 ‘F’,此时整串无效,返回 0。注意:digit_1 为 0 时无效,不能单独解码,所以这一分支要跳过。问题:给定 s,返回不同解码方式的总数,如果完全无法解码,则返回 0。
2026-01-07 00:50:49
884
原创 Bitwise AND of Numbers Range - 题解与思路
从 left 增加到 right 的过程中,只要某一位在这个过程中经历过从 0 变 1 或从 1 变 0 的变化,那么这一位在某个数上必然是 0,按位与之后这个位就会变 0。本题保证 0 <= left, right <= 2^31 - 1,全部是非负数,即最高位为 0,不会出现符号扩展问题,所以用 >> 即可,算术右移和逻辑右移在这里表现一致。当某一位开始在 left 与 right 之间发生差异时,说明在区间 [left, right] 内,这一位必然经历了 0/1 的变化。
2026-01-06 22:55:26
643
原创 LeetCode 137「Single Number II」详解:位计数 + 模3运算 + 状态机
给定题目是 LeetCode 137「Single Number II」:在一个整数数组中,除了一个元素只出现一次以外,其余每个元素都恰好出现三次,要求在 O(n) 时间、O(1) 额外空间内找出这个只出现一次的元素。cnblogs+1。
2026-01-06 11:47:59
961
原创 LeetCode 188. Best Time to Buy and Sell Stock IV - 三维DP详解
题意 + 思路一句话概括:这是「最多进行 k 次交易」的股票买卖问题,可以用三维 DP:dp[day][transaction][hold]dp[day][transaction][hold]dp[day][transaction][hold],其中交易数按「卖出次数」计数,买入不加 1,卖出才加 1。。
2026-01-05 23:36:31
876
原创 LeetCode 123:Best Time to Buy and Sell Stock III 三维DP完全解析
这 4 个状态可以理解为把三维 dp[i][j][k] 中真正会被用到的那几类状态抽出来,省去了显式的 i 维和 j 维,从而把空间压缩到 O(1)。当 j=2 时,j+1=3>K,就没有「还能卖 3 次」这个状态,所以不能通过「卖出」到达 dp[i][2][0],只能从「昨天不持股、还能卖 2 次」继承。注意:只有在 j+1≤2 时,第二项才有效,否则不存在 dp[i-1][j+1],这时直接视为「不可能」,不会取。dp[i][j]:第 i 天结束时,不持股,之后还可以做 j 次卖出的最大利润。
2026-01-05 22:36:41
1949
原创 LeetCode 123:Best Time to Buy and Sell Stock III 三维DP完全解析
当 j=2 时,j+1=3>K,就没有「还能卖 3 次」这个状态,所以不能通过「卖出」到达 dp[i][2][0],只能从「昨天不持股、还能卖 2 次」继承。这 4 个状态可以理解为把三维 dp[i][j][k] 中真正会被用到的那几类状态抽出来,省去了显式的 i 维和 j 维,从而把空间压缩到 O(1)。注意:只有在 j+1≤2 时,第二项才有效,否则不存在 dp[i-1][j+1],这时直接视为「不可能」,不会取。先用三维 dp[i][j][k] 把「时间 / 交易次数 / 持仓状态」都写清楚。
2026-01-05 12:04:06
1162
原创 LeetCode 221:Maximal Square 动态规划详解
这道题的价值不只是写出一个通过的答案,更重要的是:习惯用“以谁为结尾/为右下角”来定义状态。这里有几个可以继续思考和练习的方向:能否自己实现一维滚动数组版本,把空间压到 O(n)?能否类比这题,去看“最大矩形(Maximal Rectangle)”、“最大全 1 子矩阵”等题?能否把“上、左、左上取 min + 1”这个模式,总结成一种“从相邻子问题扩张目标形状”的通用套路?。
2026-01-05 11:44:18
1324
原创 LeetCode 72. Edit Distance(编辑距离)动态规划详解
编辑距离是经典的动态规划问题,用于计算两个字符串之间的最小操作次数(插入、删除、替换)。核心思路是定义dp[i][j]表示将word1前i个字符转换为word2前j个字符的最小操作数。边界条件是空串转换(全插入或全删除)。状态转移分为字符相等(直接继承前状态)和不等(取删除、插入或替换中的最小值)。通过构建二维DP表,自底向上填充,最终dp[m][n]即为答案。时间复杂度O(mn),空间复杂度O(mn)。
2026-01-04 08:32:42
649
原创 LeetCode 97. 交错字符串 - 二维DP经典题解(C语言实现)
给定三个字符串 s1、s2、s3,判断 s3 是否可以由 s1 和 s2 交错组成。leetcode交错的含义是:保持 s1、s2 各自字符相对顺序不变,把它们按某种顺序“插”在一起,形成 s3。leetcode例如:s1 = “aabcc”,s2 = “dbbca”,可以拆成 “aa” + “bc” + “c” 和 “dbbc” + “a”,交错后得到 “aadbbcbcac”,所以返回 true。leetcode。
2026-01-03 03:21:30
657
深入Linux内核架构(中文版)-超高清-由Word转pdf而成
2017-05-20
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅