ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

codeforces-go 题解:LeetCode 双周赛 102「数组所有前缀的得分」—— 前缀最大值与得分累计的单遍扫描

codeforces-go 题解:LeetCode 双周赛 102「数组所有前缀的得分」—— 前缀最大值与得分累计的单遍扫描 科学计算【免费下载链接】codeforces-go算法竞赛模板库 by 灵茶山艾府 项目地址https://gitcode.com/GitHub_Trending/co/codeforces-go点击查看免费下载导读本文基于 leetcode/biweekly/102/b/README.md 中记录的双周赛 102 第二题解法完整讲解「Find the Score of All Prefixes of an Array数组所有前缀的得分」的题目定义、单遍扫描思路与多语言实现并结合 codeforces-go 仓库中对应的 b.go 实现与 b_test.go 测试工程深入展示该题在算法竞赛模板库中的落地方式。读完本文你将掌握一类维护前缀最大值 前缀累计的经典线性扫描技巧以及该仓库如何用数据文件驱动 随机对拍的方式为单函数题做验证。问题定义什么是数组所有前缀的得分题目要求对给定整数数组nums的每个前缀计算得分并返回得分数组。得分规则如下依据仓库 README 及实现对下标i取前缀nums[0..i]中的最大值mx[i] max(nums[0..i])每个位置j的单点得分定义为nums[j] mx[j]即当前元素加上到它为止的前缀最大值前缀i的得分score[i]是0..i所有单点得分之和。换句话说答案数组的第i项是一个嵌套累加score[i] Σ (nums[j] max(nums[0..j])) (j 0..i)以仓库中 b.txt 的第一组测试数据为例nums [2, 3, 7, 5, 10] 答案 [4, 10, 24, 36, 56]逐步推演验证定义前缀前缀最大值 mx单点得分 x mx累计得分 score[2]22244[2,3]33364610[2,3,7]77714101424[2,3,7,5]75712241236[2,3,7,5,10]10101020362056这正是原文档中一边遍历一边计算前缀最大值 mx以及前缀的得分之和 s的核心脉络。核心思路单遍扫描维护两个滚动变量若对每个前缀都重新扫描求最大值总复杂度会退化为 O(n²)。本题的关键洞察在于前缀最大值具有单调性mx max(mx, x)只需一次比较即可由上一个前缀的最大值递推而来且单调不减前缀得分具有累计性score[i] score[i-1] (nums[i] mx[i])后一个前缀的得分可以从前一个前缀的得分直接递推。因此只需维护两个变量mx当前遍历到的前缀最大值s当前遍历到的前缀得分累计和。每读到一个元素x先更新mx max(mx, x)再执行s x mx把s写入答案数组对应位置。整个过程中每个元素只被处理一次全程只用两个额外变量。Python 实现继承自原文档class Solution: def findPrefixScore(self, nums: List[int]) - List[int]: ans [] mx s 0 for x in nums: mx max(mx, x) # 前缀最大值 s x mx # 累加前缀的得分 ans.append(s) return ansGo 实现继承自原文档func findPrefixScore(nums []int) []int64 { ans : make([]int64, len(nums)) mx, s : 0, 0 for i, x : range nums { mx max(mx, x) // 前缀最大值 s x mx // 累加前缀的得分 ans[i] int64(s) } return ans } func max(a, b int) int { if a b { return b }; return a }两处实现需要注意的工程细节返回值类型为[]int64而非[]int由于得分随前缀不断累加n 较大时可能超出 32 位整数范围因此仓库中的 Go 解法在写入答案时显式做int64(s)转换见 b.go 第 10 行这与题目给出的返回值签名保持一致。max需要自行定义LeetCode Go 环境中早期版本的内置max并不总可用仓库实现里显式给出了func max(a, b int) int的手写版本保证模板可独立复制运行。复杂度分析时间复杂度O(n)其中 n 为nums的长度。每个元素仅进入循环一次循环体内的比较与加法均为常数操作不存在任何嵌套扫描。空间复杂度O(1)返回值数组不计入。除答案数组外仅使用mx、s与循环变量等常数个额外变量符合原文档中的结论。对于前缀类问题的滚动递推这已经是最优的线性复杂度至少要读取全部 n 个元素才能计算出每个前缀的得分。仓库中的工程实践实现、数据驱动测试与随机对拍本题在该仓库中不是孤立的题解笔记而是一套完整可运行的工程样例四件套文件位于 leetcode/biweekly/102/b/1. 可独立运行的 Go 实现 b.go仓库实现与原文档中的 Go 代码完全一致包名为main函数签名findPrefixScore(nums []int) []int64并在文件头保留出处注释。该实现可以直接放入 LeetCode 的 Go 提交框使用。2. 数据驱动的测试文件 b_test.go测试文件由copypasta/template/leetcode/generator_test.go生成包含两层验证func Test_b(t *testing.T) { targetCaseNum : 0 // -1 if err : testutil.RunLeetCodeFuncWithFile(t, findPrefixScore, b.txt, targetCaseNum); err ! nil { t.Fatal(err) } if err : testutil.RunFuncWithRandomInput(t, findPrefixScore); err ! nil { t.Fatal(err) } }第一层官方样例验证。testutil.RunLeetCodeFuncWithFile读取 b.txt逐行解析输入与期望输出并逐一断言。其底层实现在 leetcode/testutil/leetcode.go先过滤空行再按fNumIn fNumOut即入参行数 返回值行数为一组切分测试数据最后交给RunLeetCodeFuncWithExamples通过反射调用被测函数、比对输出。targetCaseNum的语义为0表示跑全部用例并启用超时检测-1表示只跑最后一组用例。第二层无尽随机对拍。testutil.RunFuncWithRandomInput会不断用随机生成的输入调用findPrefixScore与参考实现比对结果用于在官方样例之外验证算法的鲁棒性。这一机制对应 leetcode.go 中的CompareInf无尽对拍模式默认MaxTestCase math.MaxInt并利用 2 秒的DebugTLE超时窗口定义于 leetcode/testutil/config.go自动标记可能超时的用例。3. 官样例文件 b.txt文件按输入行 输出行成对组织空行会被测试框架自动忽略。仓库中共存两组用例[2,3,7,5,10] [4,10,24,36,56] [1,1,2,4,8,16] [2,4,8,16,32,64]第二组用例恰好展示了数组元素本身构成前缀最大值链每个元素都大于等于前缀中所有元素的边界形态此时单点得分恒为2*x累计得分呈 2、4、8、16、32、64 的倍增序列。运行方式在仓库根目录执行以下命令即可复现测试结果go test ./leetcode/biweekly/102/b/ -v该测试依赖testutil包测试数据文件路径b.txt以相对路径传入因此命令必须从仓库根目录发起。运行成功时go test会输出两组用例均通过的结论。总结一类可推广的前缀递推技巧本题的算法本质是把求前缀统计量从朴素的两层循环优化为单遍滚动凡是统计量可以由前缀统计量 当前元素递推前缀最大值、前缀和、前缀最值差、前缀相等段等的问题都可以考虑这种 O(n) 的单遍扫描维护的滚动变量数量通常等于递推关系中的状态数——本题恰好是两个mx与s二者更新顺序固定先更新前缀最大值再更新依赖它的累计得分。结合仓库 leetcode/biweekly/102/b/ 下的实现与测试四件套读者既可以把它当作一份可直接复制提交的 LeetCode 题解也可以作为学习 codeforces-go 仓库函数题数据驱动测试 随机对拍工程范式的最小样例。赞分享科学计算【免费下载链接】codeforces-go算法竞赛模板库 by 灵茶山艾府 项目地址https://gitcode.com/GitHub_Trending/co/codeforces-go点击查看免费下载相关推荐LeetCode 1589 所有排列中的最大和差分数组 前缀和 贪心配对的完整解法LeetCode 1589 所有排列中的最大和差分数组 前缀和 贪心配对的完整解法 导读 本文以本仓库题解文档 problems/1589.maxim文档教程知识库LeetCode 1422 拆分字符串使得分最大化前缀和、滚动计数与代数优化的四级递进解法LeetCode 1422 拆分字符串使得分最大化前缀和、滚动计数与代数优化的四级递进解法 本文以 LeetCode 1422「Maximum Score A示例工程教程CS-Notes 剑指 Offer 详解构建乘积数组——前缀积 × 后缀积的两遍扫描解法CS Notes 剑指 Offer 详解构建乘积数组——前缀积 × 后缀积的两遍扫描解法 本篇基于 66. 构建乘积数组 展开讲解剑指 Offer 中构建知识库文档教程上一篇如何高效使用DeepCreamPy深度学习图像修复完整实战指南下一篇zincobserve查询性能剖析从SQL到存储的全链路优化创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表