LeetCode-Go 题解 1313. Decompress Run-Length Encoded List行程长度编码数组解压的 Go 实现【免费下载链接】LeetCode-Go✅ Solutions to LeetCode by Go, 100% test coverage, runtime beats 100% | LeetCode 题解项目地址: https://gitcode.com/GitHub_Trending/le/LeetCode-Go本题解围绕 LeetCode 第 1313 题「解压行程长度编码列表」展开对应本仓库 leetcode/1313.Decompress-Run-Length-Encoded-List/README.md 及其配套源码。文章将完整讲解行程长度编码Run-Length EncodingRLE的解压规则、题目约束与两个示例深入剖析仓库中 Go 解法的核心思路与复杂度并结合同目录测试文件说明如何在本仓库中验证实现。读完本文你将掌握这类「按频次展开数组」题目的标准解压套路并能独立写出可复用的 Go 实现。题目背景什么是行程长度编码RLE行程长度编码是一种简单的无损压缩方式核心思想是把「连续出现的相同值」记录为「出现次数 值」的形式。本题给出的压缩列表nums正是这种编码的线性存储数组中元素按相邻成对排列每对[freq, val]表示解压后应有freq个值为val的元素。具体对应关系为[freq, val] [nums[2*i], nums[2*i1]] i 0也就是说偶数下标nums[0]、nums[2]、nums[4]…存放的是频次freq紧随其后的奇数下标nums[1]、nums[3]、nums[5]…存放的是对应的值val。解压时只需从左到右依次把每个val复制freq份最后拼接所有子列表即可。题目要求与约束输入一个整数列表nums表示经过行程长度编码压缩的列表。输出解压后的列表。题目给出的两个示例示例 1Input: nums [1,2,3,4] Output: [2,4,4,4]解释第一对[1,2]表示freq 1、val 2生成子列表[2]第二对[3,4]表示freq 3、val 4生成子列表[4,4,4]拼接[2] [4,4,4]得到[2,4,4,4]。示例 2Input: nums [1,1,2,3] Output: [1,3,3]解释第一对[1,1]生成[1]第二对[2,3]生成[3,3]拼接得到[1,3,3]。约束条件2 nums.length 100输入数组长度最小为 2最大为 100nums.length % 2 0数组长度一定是偶数保证每对[freq, val]都能完整配组1 nums[i] 100所有元素均为正整数频次与值都落在 1 到 100 之间。从约束可以看出本题规模很小输入长度不超过 100单个频次不超过 100即使使用最简单的双层循环也能轻松通过是典型的入门级模拟题。解题思路按奇偶下标成对展开原文档给出的解题思路非常清晰下标从 0 开始奇数位下标对应的元素是前一个偶数位下标元素应重复的次数把该值重复append对应次数即可最终输出解压后的数组。用自然语言描述算法流程初始化一个空的结果切片res用步长为 2 的循环遍历nums每次取出当前偶数下标i作为频次下标内层循环执行nums[i]次每次把nums[i1]追加到res末尾遍历结束后返回res。这种做法的关键在于利用数组下标奇偶性天然切分出[freq, val]配对外层循环i 2保证了每一对只处理一次内层循环负责把val按频次复制。整个过程无需额外状态变量也无需处理长度边界——因为题目保证nums.length为偶数。仓库源码实现本仓库在 leetcode/1313.Decompress-Run-Length-Encoded-List/1313. Decompress Run-Length Encoded List.go 中给出了与文档一致的具体实现package leetcode func decompressRLElist(nums []int) []int { res : []int{} for i : 0; i len(nums); i 2 { for j : 0; j nums[i]; j { res append(res, nums[i1]) } } return res }逐行解读这段代码res : []int{}声明空切片存放解压结果for i : 0; i len(nums); i 2外层循环以步长 2 扫描i始终指向每对元素中的频次位置for j : 0; j nums[i]; j内层循环执行freq即nums[i]次res append(res, nums[i1])每次把该对的值nums[i1]追加进结果return res返回完整解压列表。需要注意函数名decompressRLElist使用小写开头是包内私有函数。由于本仓库每个题解目录都是一个独立的package leetcode包见 go.mod 的模块定义该函数仅在当前题解包内可见测试文件与它处于同一包内可以直接调用。复杂度分析时间复杂度外层循环遍历n/2对元素n为nums长度内层循环总执行次数等于所有频次之和即sum(nums[2*i])而这恰好就是解压后结果数组的长度L。因此整体时间复杂度为O(n L)其中n是输入长度L是输出长度。受约束限制n 100、L 100 × 50 5000规模极小。空间复杂度除返回的结果切片res外只使用了i、j两个循环变量额外空间为O(1)。结果切片所占空间属于输出本身通常不计入额外空间复杂度。测试用例与验证方式同目录下的 leetcode/1313.Decompress-Run-Length-Encoded-List/1313. Decompress Run-Length Encoded List_test.go 为本题提供了表驱动风格的测试package leetcode import ( fmt testing ) type question1313 struct { para1313 ans1313 } // para 是参数 // one 代表第一个参数 type para1313 struct { nums []int } // ans 是答案 // one 代表第一个答案 type ans1313 struct { one []int } func Test_Problem1313(t *testing.T) { qs : []question1313{ { para1313{[]int{1, 2, 3, 4}}, ans1313{[]int{2, 4, 4, 4}}, }, { para1313{[]int{1, 1, 2, 3}}, ans1313{[]int{1, 3, 3}}, }, { para1313{[]int{}}, ans1313{[]int{}}, }, } fmt.Printf(------------------------Leetcode Problem 1313------------------------\n) for _, q : range qs { _, p : q.ans1313, q.para1313 fmt.Printf(【input】:%v , p) fmt.Printf(【output】:%v \n, decompressRLElist(p.nums)) } fmt.Printf(\n\n\n) }从测试源码可以观察到三个细节覆盖两个官方示例用例 1 与用例 2 与题目示例完全一致验证基本逻辑额外覆盖空输入测试还包含nums []的场景。虽然该用例超出了题目约束约束要求nums.length 2但它恰好可以验证实现的防御性——外层循环条件i len(nums)在空数组下直接不成立函数返回空切片不会越界或 panic表驱动组织方式通过para1313参数与ans1313期望答案两个结构体成对组织用例这是本仓库各题解测试的统一风格便于后续继续追加新用例。需要说明的是该测试目前以打印输入输出为主使用fmt.Printf并未通过t.Error之类的断言函数做严格比对运行后可从终端输出人工核对【output】与期望结果是否一致。这与本仓库其余题解的测试风格保持一致。在仓库根目录运行以下命令即可单独执行本题测试go test -v ./leetcode/1313.Decompress-Run-Length-Encoded-List/ -run Test_Problem1313若想对整个仓库运行覆盖测试并生成 coverage.txt可执行仓库根目录提供的脚本./gotest.sh该脚本使用go test -covermodeatomic -coverprofilecoverage.txt ./leetcode/...一次性为所有题解包生成合法的覆盖率文件项目描述中「100% test coverage」的工程目标正是通过这套流程来保障的。边界情况与进阶优化边界情况一最小合法输入。当nums [1, x]时只有一对元素函数只执行一次内层循环返回[x]符合预期。边界情况二全部为最小频次。当所有偶数位都为 1 时如[1,a,1,b]内层循环每对只执行一次结果就是所有奇数位值按原顺序排列的列表。进阶优化预分配切片容量。原实现从空切片开始反复appendGo 的切片扩容机制会在容量不足时重新分配并拷贝底层数组。由于解压后总长度可预先算出即所有偶数下标元素之和可以先统计总长度再一次性分配package leetcode func decompressRLElistWithCap(nums []int) []int { total : 0 for i : 0; i len(nums); i 2 { total nums[i] } res : make([]int, 0, total) for i : 0; i len(nums); i 2 { for j : 0; j nums[i]; j { res append(res, nums[i1]) } } return res }该变体将空间分配次数降为 1 次避免扩容拷贝开销。不过在本题的约束规模下输出最长 5000 个元素两种写法性能差异微乎其微仓库保留的是代码最简洁的双层循环版本便于读者聚焦算法本身。小结LeetCode 1313 是一道以行程长度编码为背景的模拟题核心只有一步把数组按相邻两元素[freq, val]成组切分再按频次展开拼接。本仓库 leetcode/1313.Decompress-Run-Length-Encoded-List/ 目录下的 题解文档、实现代码 与 测试文件 三件套构成了完整的解题闭环其中双层循环 步长 2 的遍历模式值得作为模板记忆可平滑迁移到其他「按组处理数组元素」的题目如按对、按块解压等场景中。【免费下载链接】LeetCode-Go✅ Solutions to LeetCode by Go, 100% test coverage, runtime beats 100% | LeetCode 题解项目地址: https://gitcode.com/GitHub_Trending/le/LeetCode-Go创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考