ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

LeetCode-Go 题解:1486. XOR Operation in an Array 的模拟实现与位运算优化剖析

LeetCode-Go 题解:1486. XOR Operation in an Array 的模拟实现与位运算优化剖析 LeetCode-Go 题解1486. XOR Operation in an Array 的模拟实现与位运算优化剖析【免费下载链接】LeetCode-Go✅ Solutions to LeetCode by Go, 100% test coverage, runtime beats 100% | LeetCode 题解项目地址: https://gitcode.com/GitHub_Trending/le/LeetCode-Go导读本文围绕 LeetCode 第 1486 题「XOR Operation in an Array」完整呈现 LeetCode-Go 仓库收录的 Go 模拟解法及其测试用例并从位运算角度推导奇偶性规律与基于连续整数异或公式的 O(1) 数学解法。读完本文你将掌握异或XOR运算在序列场景下的两种求解路径可直接 AC 的 O(n) 模拟以及可用于大参数场景的常数时间优化。一、题目回顾题目原文摘自 本题 READMEGiven an integernand an integerstart.Define an arraynumswherenums[i] start 2*i(0-indexed) andn nums.length.Return the bitwise XOR of all elements ofnums.即给定整数n与start构造长度为n的数组nums其中第i个元素为start 2*i返回该数组全部元素按位异或后的结果。约束条件Constraints1 n 10000 start 1000n nums.length示例汇总与 单元测试 中的用例一一对应示例nstart数组 nums输出150[0, 2, 4, 6, 8]8243[3, 5, 7, 9]8317[7]74105[5, 7, 9, 11, 13, 15, 17, 19, 21, 23]2二、题目大意题面直译给你两个整数n和start数组nums定义为nums[i] start 2*i下标从 0 开始且n nums.length请返回nums中所有元素按位异或XOR后得到的结果。这是一道典型的位运算入门题序列构造规则极其简单等差数列公差为 2考察的是对异或运算语义的理解以及一次线性遍历的实现能力。三、基础回顾按位异或XOR的三条核心性质在展开题解前先回顾异或运算的几条基本性质它们是理解本题以及后续数学推导的基础归零律x ^ x 0任何数与自己异或结果为 0恒等律x ^ 0 x任何数与 0 异或保持不变交换律与结合律异或运算可任意交换、组合运算顺序因此异或一个序列时不必关心元素先后。此外对任意偶数2k有(2a) ^ (2b) (a ^ b) 1——因为两个偶数的最低位都是 0其异或结果的最低位也是 0高位部分等价于各自右移一位后再异或、最后左移一位恢复。这条性质正是第五节 O(1) 推导的基石。四、解法一按题意模拟仓库收录解法4.1 思路本题最直接的做法就是「照抄题意」从i 0到i n-1依次生成元素start 2*i用一个累加变量逐个做异或。由于异或满足交换律与结合律累积顺序不影响结果。4.2 代码实现LeetCode-Go 仓库在 1486. XOR Operation in an Array.go 中收录的实现如下package leetcode func xorOperation(n int, start int) int { res : 0 for i : 0; i n; i { res ^ start 2*i } return res }实现要点初始值res 0借助「恒等律」x ^ 0 x使第一次异或不受干扰循环体内直接以内联表达式start 2*i生成元素无需额外分配数组空间开销保持 O(1)函数签名xorOperation(n int, start int) int与 LeetCode 题面要求完全一致便于直接移植到在线评测环境。4.3 复杂度分析时间复杂度O(n)单次线性扫描n 1000时最多 1000 次异或空间复杂度O(1)仅使用常数个变量。在本题约束n 1000下该模拟解法已经完全足够这也是仓库将其作为标准解法的原因。五、解法二位运算视角的 O(1) 数学优化模拟解法虽然直观但仔细观察序列start 2*i的结构可以发现其中隐藏着可以数学化的规律。以下推导属于对仓库收录解法的延伸思考用于帮助理解位运算的深层性质仓库本身以第四节模拟解法为准。5.1 奇偶性观察所有元素共享同一奇偶性由于2*i恒为偶数start 2*i与start的奇偶性必然相同。于是若start为偶数则nums中所有元素均为偶数最低位LSB恒为 0若start为奇数则nums中所有元素均为奇数最低位恒为 1。对于奇数起点的情况n个最低位均为 1 的元素做异或最低位的最终值等于n mod 2奇数个 1 异或得 1偶数个 1 异或得 0。这一观察把「最低位」与「其余高位」的求解拆分开来。5.2 把元素改写为「两倍 偏移」令s start / 2向下取整则nums[i] start 2*i 2*(s i) (start mod 2)即每个元素都可以写成「偶数部分2*(si)」与「起点奇偶偏移start mod 2」的组合。结合第三节的移位性质整个序列的异或结果满足XOR(nums) 2 * (XOR of s, s1, ..., sn-1) (start mod 2) * (n mod 2)其中(start mod 2) * (n mod 2)就是最低位的贡献只有起点为奇数且元素个数为奇数时最低位才为 1。5.3 连续整数区间异或的 O(1) 公式于是问题被归约为「求一段连续整数区间[lo, hi]的异或」。利用著名的周期为 4 的模式1 ^ 2 ^ ... ^ x的取值仅由x mod 4决定x mod 4XOR(1..x)0x112x 130例如1^2^3 01^2^3^4 41^2^3^4^5 1依此循环。由于 0 参与异或不改变结果XOR(0..x)与XOR(1..x)相等区间[lo, hi]的异或即XOR(1..hi) ^ XOR(1..lo-1)。5.4 O(1) 完整实现综合上述推导可写出常数时间版本package leetcode // xor1toN 返回 1 ^ 2 ^ ... ^ x基于模 4 周期模式 func xor1toN(x int) int { switch x % 4 { case 0: return x case 1: return 1 case 2: return x 1 default: // x%4 3 return 0 } } // xorRange 返回 lo ^ (lo1) ^ ... ^ hi func xorRange(lo, hi int) int { return xor1toN(hi) ^ xor1toN(lo-1) } func xorOperationO1(n int, start int) int { s : start 1 // 等价于 start / 2 var base int if s 0 { base xor1toN(n - 1) } else { base xorRange(s, sn-1) } res : base 1 // 偶数部分整体左移一位 if start1 1 n1 1 { res | 1 // 最低位贡献 } return res }用题目四个示例逐一验算结果与预期完全一致示例计算过程结果n5, start0s0baseXOR(0..4)4418LSB 贡献 08 ✓n4, start3s1baseXOR(1..4)4418n 为偶 LSB 贡献 08 ✓n1, start7s3baseXOR(3..3)3316奇起奇个 LSB 贡献 17 ✓n10, start5s2baseXOR(2..11)1112n 为偶 LSB 贡献 02 ✓该版本时间复杂度为 O(1)空间复杂度仍为 O(1)。尽管在本题约束下它的优势并不明显但理解其推导过程对处理「大范围等差序列异或」类问题例如n高达 10⁹ 的场景非常有价值。六、测试验证仓库测试用例与运行方式6.1 测试用例结构仓库为本题提供了完整的单元测试文件 1486. XOR Operation in an Array_test.go采用该仓库统一的「参数/答案」结构体组织用例type question1486 struct { para1486 ans1486 } type para1486 struct { n int start int } type ans1486 struct { one int }Test_Problem1486中依次注册了(5, 0) → 8、(4, 3) → 8、(1, 7) → 7、(10, 5) → 2四组用例与题目给出的四个示例一一对应。需要说明的是该测试采用fmt.Printf打印输入与输出、人工核对结果的方式未使用t.Errorf断言这也是仓库部分早期题目测试的书写风格。6.2 运行测试在仓库根目录下运行注意本题目录名包含空格需要引号包裹路径go test -v ./leetcode/1486.XOR-Operation-in-an-Array/若希望跑全仓库的覆盖率统计可执行仓库自带的 gotest.shbash gotest.sh该脚本一次性对./leetcode/...全部包执行go test -covermodeatomic -coverprofilecoverage.txt产出合法的覆盖率文件coverage.txt项目根目录下已有一份历史结果。项目 go.mod 声明了go 1.19与github.com/halfrost/LeetCode-Go模块路径并通过对structures、template等子模块的replace指令完成本地依赖关联因此直接go test即可运行无需额外安装第三方包。七、总结维度解法一模拟解法二数学推导核心思想按题意逐元素累积异或奇偶性拆分 连续整数区间异或公式时间复杂度O(n)O(1)空间复杂度O(1)O(1)代码量极小易读易维护需理解异或性质代码稍长适用场景本题约束n ≤ 1000下首选大规模序列、追求常数时间本题的价值不在于「难」而在于它同时覆盖了两种典型思维一是「工程思维」——严格按题意模拟、保证正确性与可读性对应仓库收录解法二是「算法思维」——从序列的数学结构等差数列、奇偶一致、移位等价出发将线性扫描压缩为常数时间。建议读者先掌握模拟解法再对照本文第五节的推导独立复现 O(1) 版本从而把位运算的底层性质内化为解题直觉。【免费下载链接】LeetCode-Go✅ Solutions to LeetCode by Go, 100% test coverage, runtime beats 100% | LeetCode 题解项目地址: https://gitcode.com/GitHub_Trending/le/LeetCode-Go创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表