
LeetCode-Go 题解1287. Element Appearing More Than 25% In Sorted Array —— 有序数组中的步长比较法【免费下载链接】LeetCode-Go✅ Solutions to LeetCode by Go, 100% test coverage, runtime beats 100% | LeetCode 题解项目地址: https://gitcode.com/GitHub_Trending/le/LeetCode-Go本篇指南围绕 LeetCode 第 1287 题「Element Appearing More Than 25% In Sorted Array」展开结合开源仓库 LeetCode-Go 中的题目文档、Go 实现与单元测试讲解如何利用数组非递减有序这一前提在 O(n) 时间、O(1) 空间内定位出现次数超过总数 25% 的唯一元素。读完本篇你将掌握该题的数学观察、最优解推导、源码实现细节以及仓库内的测试验证方式。题目描述英文原题Given an integer arraysortedin non-decreasing order, there is exactly one integer in the array that occurs more than 25% of the time. Return that integer.中文大意给你一个非递减的有序整数数组已知这个数组中恰好有一个整数它的出现次数超过数组元素总数的 25%。请你找到并返回这个整数。题目核心约束如下来自题目文档1 arr.length 10^40 arr[i] 10^5数组按非递减顺序排列有序是本题的题眼恰好存在唯一一个整数出现次数严格大于n / 4示例Input: arr [1,2,2,6,6,6,6,7,10] Output: 6在示例中数组长度n 925% × 9 2.25元素6出现了 4 次4 2.25因此返回6。解题思路把频次条件转化为位置条件关键观察25% 阈值与步长 n/4 的关系常规思路是统计每个元素的出现次数哈希表计数但那样需要 O(n) 的额外空间。本题可以做到 O(1) 空间秘诀在于数组是有序的。由于数组按非递减排列相同元素必然连续聚集在一起。设目标元素出现次数为cnt且满足cnt n / 4这意味着如果我们把数组按步长n/4分段观察目标元素形成的连续区间长度必然严格超过n/4。更直接地说假设目标元素从下标i开始连续出现cnt次那么i cnt - 1 i n/4 因为 cnt n/4即 cnt n/4 1因此必然存在一个位置j i n/4使得arr[i] arr[in/4]。换句话说只要扫描过程中发现arr[i] arr[in/4]arr[i]就是那个占比超过 25% 的元素。反证法确认正确性为什么这个判定是充分且必要的必要性由上述推导保证目标元素一定满足arr[i] arr[in/4]。充分性方面题目已保证恰好只有一个元素出现次数超过 25%而数组有序使得相等元素连续所以一旦某个arr[i]与其相隔n/4的位置值相等该元素连续区间长度必然大于n/4即满足题意可以直接返回。为什么循环上界是 n - n/4仓库实现源码文件中的循环条件是i n-n/4func findSpecialInteger(arr []int) int { n : len(arr) for i : 0; i n-n/4; i { if arr[i] arr[in/4] { return arr[i] } } return -1 }当i取到n-n/4-1时in/4 n-1仍在数组范围内不会越界再往后in/4就会超出数组末尾因此循环只需走到n-n/4-1为止。由于题目保证一定存在答案循环内必然提前返回return -1只是函数签名的兜底分支理论上不会执行测试中也验证了这一点。复杂度分析时间复杂度O(n)最坏情况下需要遍历约n - n/4个位置做一次比较空间复杂度O(1)只使用了常数个变量无需哈希表或额外数组。对比哈希计数方案O(n) 时间 O(n) 空间本解法在空间上做到了极致这正是有序数组 步长比较范式的价值所在。单元测试与仓库验证仓库为本题提供了完整的表驱动测试见测试文件测试结构遵循该仓库一贯的question/para/ans约定type question1287 struct { para1287 ans1287 } type para1287 struct { one []int } type ans1287 struct { one int } func Test_Problem1287(t *testing.T) { qs : []question1287{ { para1287{[]int{1, 2, 2, 6, 6, 6, 6, 7, 10}}, ans1287{6}, }, { para1287{[]int{1, 2, 3, 4, 5}}, ans1287{-1}, }, } ... }测试覆盖了两个典型场景命中场景[1, 2, 2, 6, 6, 6, 6, 7, 10]元素6出现 4 次超过 25%期望输出6兜底场景[1, 2, 3, 4, 5]没有任何元素超过 25%该输入实际上不满足题目恰好存在一个的前提用于验证return -1的兜底分支不会误报。如何运行测试在仓库根目录下使用 Go 1.19见 go.mod即可运行本题测试go test -v -run Test_Problem1287 ./leetcode/1287.Element-Appearing-More-Than-In-Sorted-Array/仓库的 gotest.sh 脚本还提供全量覆盖率验证方式可对整个./leetcode/...包执行带覆盖率的测试go test -covermodeatomic -coverprofilecoverage.txt ./leetcode/...这与仓库100% test coverage的项目定位一致每个题目目录都配套独立的*_test.go测试文件。扩展讨论同类问题的通用思路本题虽为 Easy 难度但其步长比较技巧可以推广到一类问题超过一半 50%可用摩尔投票法Boyer-Moore Majority Vote或步长改为n/2做比较超过 1/3 33%可能出现至多两个候选元素需要结合计数验证超过 1/4 25%正是本题步长n/4的单次扫描即可解决。核心思想一致在有序或可排序的数组中占比超过1/k的元素必然出现在按步长n/k划分的采样点上利用这一点可以把频次统计降维成相邻采样点比较从而以 O(1) 额外空间完成求解。小结本题唯一难点在于发现有序与25% 阈值的组合可以转化为arr[i] arr[in/4]的简单判定仓库实现仅 8 行时间复杂度 O(n)、空间复杂度 O(1)是同类频次阈值题目的极简范本配套的题目文档与单元测试共同构成了题目 → 思路 → 实现 → 验证的完整闭环可直接参照该目录结构在 LeetCode-Go 仓库中检索和学习其他题解。【免费下载链接】LeetCode-Go✅ Solutions to LeetCode by Go, 100% test coverage, runtime beats 100% | LeetCode 题解项目地址: https://gitcode.com/GitHub_Trending/le/LeetCode-Go创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考