Codewars Madhav数组JS解法未通过全部测试,求问题排查
Madhav数组判断函数的遗漏问题分析
问题定义
Madhav数组的特性是:a[0] = a[1] + a[2] = a[3] + a[4] + a[5] = a[6] + a[7] + a[8] + a[9] = ...
要求实现一个函数,判断给定数组是否为Madhav数组,是则返回true,否则返回false。边界规则:长度为0或1的数组不视为Madhav数组。
测试用例:
Test.assertDeepEquals(isMadhavArray([2,1,1]), true); Test.assertDeepEquals(isMadhavArray([2,1,1,4,-1,-1]), true);
我的解法
function isMadhavArray(arr) { if (arr.length < 3) { return false; } let goal = arr[0]; arr.shift(); let n = 2; while (arr.length > 0) { let remove_items = arr.splice(0, n); let sum = remove_items.reduce((a, c) => a + c, 0); if (goal == sum) { n++ } else { return false; } } return true; }
该解法通过了113个测试用例中的111个,请问我遗漏了什么情况?
遗漏情况分析
你漏了数组长度不符合Madhav数组结构要求的场景。
Madhav数组的总长度必须满足公式:1 + 2 + 3 + ... + m = m*(m+1)/2,其中m是大于等于2的整数。比如测试用例里的长度3对应m=2(1+2=3),长度6对应m=3(1+2+3=6),长度10对应m=4(1+2+3+4=10)等等。如果数组长度不在这个序列里,哪怕分组求和都等于a[0],也不能算Madhav数组。
举个反例:数组[3,1,2,3],长度为4,不符合上述公式。你的代码执行时:
- 长度≥3,取goal=3,数组变为
[1,2,3] - n=2,截取前2个元素
[1,2]求和等于3,n自增为3 - 剩余数组是
[3],截取3个元素(实际只能取到1个)求和等于3,循环结束返回true,但这个数组根本不是合法的Madhav数组。
解决方法是在函数开头先校验数组长度是否符合要求,同时建议避免修改原数组,改用索引遍历更稳妥:
function isMadhavArray(arr) { const len = arr.length; // 边界判断+长度合法性校验 if (len < 3) return false; const m = Math.floor(Math.sqrt(2 * len)); if (m * (m + 1) / 2 !== len) { return false; } const goal = arr[0]; let n = 2; let start = 1; while (start < len) { const end = start + n; const sum = arr.slice(start, end).reduce((a, c) => a + c, 0); if (sum !== goal) return false; start = end; n++; } return true; }
内容的提问来源于stack exchange,提问作者ELND
相关产品推荐
相关产品推荐

