
madhav 数组要求首元素等于后续连续分组(长度递增的等差段)之和;需严格验证每组元素数量与和值,避免因数组截断不完整导致误判。
madhav 数组要求首元素等于后续连续分组(长度递增的等差段)之和;需严格验证每组元素数量与和值,避免因数组截断不完整导致误判。
Madhav 数组是一种具有特定累加结构的整数数组,其定义如下:
- 第 0 个元素
a[0]必须等于第 1–2 项之和(即a[1] + a[2]), - 同时也必须等于第 3–5 项之和(即
a[3] + a[4] + a[5]), - 接着等于第 6–9 项之和(共 4 项),依此类推……
形式化地说,第k个分组(从k = 1开始计数)应包含k+1个元素(注意:首组为 2 项,次组为 3 项,第三组为 4 项……),且所有分组的和必须严格等于a[0]。
⚠️ 关键约束:
- 长度 ≤ 1 的数组不构成 Madhav 数组(无分组可比);
- 长度 = 2 的数组也不合法(无法形成至少一个完整分组,因首分组需 2 项,但此时
a[0]已被占用,剩余仅 1 项); - 最易忽略的边界条件:最后一组必须恰好包含预期数量的元素。若剩余元素不足,却仍凑出相同和值,将导致假阳性(false positive)。
例如,输入 [2, 1, 1, 1, 1]:
-
a[0] = 2,目标和为 2; - 第 1 组(2 项):
a[1]+a[2] = 1+1 = 2✅; - 第 2 组(3 项):理论上需
a[3]~a[5],但数组只剩a[3], a[4](仅 2 项); - 若用
splice(0, 3),实际只取到[1, 1],其和为2—— 错误地通过校验。
✅ 正确行为:检测到该组长度,应立即返回 <code>false。
以下是推荐的高效、非破坏性实现(避免 splice,使用索引遍历):
立即学习“Java免费学习笔记(深入)”;
function isMadhavArray(arr) {
// 基础长度检查:至少需要 1(首项)+ 2(第一组)= 3 个元素
if (arr.length < 3) return false;
const target = arr[0];
let startIdx = 1; // 下一个待处理元素的起始索引
let groupSize = 2; // 当前分组应含元素个数(第1组=2,第2组=3,...)
while (startIdx < arr.length) {
const endIdx = startIdx + groupSize;
// 检查是否足够取满 groupSize 个元素
if (endIdx > arr.length) {
return false; // 末尾元素不足,非法
}
// 计算当前分组和
let sum = 0;
for (let i = startIdx; i < endIdx; i++) {
sum += arr[i];
}
if (sum !== target) {
return false;
}
startIdx = endIdx; // 移动到下一组起点
groupSize++; // 分组大小递增
}
return true;
}? 进阶优化(预检三角形长度):
Madhav 数组总长度必为 1 + 2 + 3 + ... + k = k(k+1)/2 + 1(含首项)。令 n = arr.length,则 n - 1 必须是三角形数,即方程 k(k+1)/2 = n - 1 有正整数解 k。可通过判别式快速验证:
const len = arr.length; if (len < 3 || Math.sqrt(8 * (len - 1) + 1) % 1 !== 0) return false;
此检查可在循环前执行,提前排除所有长度不合规的输入,提升性能。
✅ 总结:
- 勿修改原数组(避免
splice); - 每次分组前显式校验元素数量是否充足;
- 理解 Madhav 结构本质:分组长度序列为
2, 3, 4, ..., k,总数据长度 =1 + Σi=2^k i = 1 + k(k+1)/2 − 1 = k(k+1)/2; - 单元测试务必覆盖临界用例:
[2,1,1,1,1](缺项)、[1](过短)、[5,2,3,1,1,1](和对但末组缺项)等。


















