算法内容
本文件实现 LeetCode 179「最大数」。目标是把一组非负整数重新排列,使拼接后的数字最大。
代码先将整数转换为字符串,再通过自定义比较函数排序。比较两个字符串时,本质上要判断 a + b 和 b + a 哪个更大,排序后顺序拼接即可。实现里手写了整数转字符串和较复杂的循环比较逻辑,并对全 0 的情况做了处理,避免返回多个前导 0。时间复杂度主要来自排序,为 O(n log n * L),L 为数字字符串比较成本。
算法实现
1 |
|
本文件实现 LeetCode 179「最大数」。目标是把一组非负整数重新排列,使拼接后的数字最大。
代码先将整数转换为字符串,再通过自定义比较函数排序。比较两个字符串时,本质上要判断 a + b 和 b + a 哪个更大,排序后顺序拼接即可。实现里手写了整数转字符串和较复杂的循环比较逻辑,并对全 0 的情况做了处理,避免返回多个前导 0。时间复杂度主要来自排序,为 O(n log n * L),L 为数字字符串比较成本。
1 |
|
本文件实现 LeetCode 198「打家劫舍」。问题要求在不能偷相邻房屋的限制下,获得最大金额。
代码采用自顶向下的记忆化搜索。maxRob(nums, i) 表示上一次选择位置为 i 后,从后续可选位置中能得到的最大收益;每次只尝试选择 i + 2 或 i + 3,用 mem[i + 2] 缓存状态结果。入口从 -2 开始,等价于还没有选择任何房屋。时间复杂度 O(n),空间复杂度 O(n)。文件中的 main 用一组样例数据做本地验证。
1 |
|
本文件实现 LeetCode 2049「统计最高分的节点数目」。题目要求删除每个节点后,计算剩余各连通块大小的乘积,并统计最高分节点数量。
第一版使用 unordered_map<int, vector<int>> 建树,先通过 DFS 计算每个节点子树大小,再枚举节点计算分数:父侧连通块大小为 n - size[i],每个子树连通块大小为对应子节点的 size。SolutionBetter 针对二叉树性质,用 vector<pair<int, int>> 保存左右孩子,避免 map 和动态 vector 带来的额外开销。整体时间复杂度 O(n),空间复杂度 O(n)。
1 |
|
本文件实现 LeetCode 2055「蜡烛之间的盘子」。目标是对多个区间查询,统计区间内两根蜡烛之间的盘子数量。
代码预处理三个数组:v 为盘子数量前缀和,left[i] 表示位置 i 左侧最近蜡烛下标,right[i] 表示位置 i 右侧最近蜡烛下标。对于查询 [l, r],先找到 right[l] 和 left[r] 作为区间内最靠内的两根蜡烛,如果左蜡烛在右蜡烛左侧,就用前缀和相减得到盘子数。预处理 O(n),每次查询 O(1),总复杂度 O(n + q)。
1 |
|
本文件实现 LeetCode 207「课程表」。问题可以转化为判断有向图中是否存在环。
代码使用拓扑排序。m 数组统计每门课的入度,g 存储从先修课程指向后续课程的邻接表。先把所有入度为 0 的课程入栈,然后不断弹出课程并降低后继节点入度;当某个后继入度降为 0 时继续入栈。最后如果存在未访问课程,说明图中有环,无法完成所有课程。时间复杂度 O(V + E),空间复杂度 O(V + E)。
1 |
|
本文件实现 LeetCode 399「除法求值」。方程 a / b = value 可以看作带权有向图中的两条边:a -> b 权重为 value,b -> a 权重为倒数。
代码先构建变量名到节点索引的映射,并为每个变量维护相邻节点和边权。查询时,如果变量不存在返回 -1;如果起点终点相同返回 1;否则从起点做图搜索,沿路径累计乘积,找到目标节点时返回路径权重乘积。构图复杂度 O(E),单次查询最坏 O(V + E)。文件中还包含打印图结构和本地测试的辅助代码。
1 |
|
本文件尝试解决 LeetCode 546「移除盒子」。题目要求每次移除一段连续同色盒子并获得长度平方分数,求最大总分。
代码先把连续相同颜色压缩成链表节点,每个节点记录颜色和连续数量;随后根据某种启发式规则选择颜色进行删除,并在删除后合并相邻同色段。这个实现更像一次贪心尝试:优先选取剩余数量差值较小的颜色,而不是经典题解中的区间动态规划。因此它有助于理解压缩连续段和链表合并操作,但不能保证得到全局最优解。标准解法通常使用三维 DP dp[l][r][k] 表示区间和右侧同色累积数量。
1 |
|
本文件实现 LeetCode 669「修剪二叉搜索树」。目标是删除 BST 中所有不在 [low, high] 范围内的节点,并保持剩余结构仍为二叉搜索树。
代码利用 BST 性质:如果当前根值大于 high,合法节点只可能在左子树;如果当前根值小于 low,合法节点只可能在右子树。find(TreeNode** root) 通过二级指针直接修改父节点指向,先把当前根调整到合法范围,再递归修剪左右子树。每个节点最多访问一次,时间复杂度 O(n),递归空间复杂度 O(h)。
1 | struct TreeNode { |
本文件实现 LeetCode 798「得分最高的最小轮调」。旋转后,如果元素值不大于它的新下标,该元素得 1 分,要求返回得分最高且下标最小的旋转值。
代码使用差分数组记录每个元素在哪些旋转区间内可以得分。对位置 i 的元素 nums[i],计算它得分的旋转区间 [low, high),在差分数组中做区间加一;当区间跨过 0 时额外给 diff[0] 加一。最后对差分数组求前缀和,得到每个旋转值的总分,并保留第一次出现的最大值位置。时间复杂度 O(n),空间复杂度 O(n)。
1 |
|
本文件实现牛客 KY191「矩阵幂」的一个基础版本。程序读取矩阵阶数 n 和幂次 k,再读取 n 阶矩阵并输出矩阵的 k 次幂。
mul 完成普通矩阵乘法,并把结果写回第一个矩阵;matPow 根据 pow 的取值执行固定次数的乘法。当前实现只显式处理 1 到 5 次幂,适合题目幂次范围较小或练习矩阵乘法流程的场景。矩阵乘法单次时间复杂度 O(n^3)。如果 k 更大,通常需要改为快速幂,将复杂度优化为 O(n^3 log k)。
1 |
|