HackerRank Picking Numbers挑战的Ruby实现与代码失效原因解析
代码异常原因拆解
核心运行错误点
- 数组越界触发运行时中断
内层循环未对遍历索引做上边界限制,当j递增到等于数组长度时,a[j]会返回nil。再加上代码冗余调用了to_int方法(排序后数组内元素本身就是整数,不需要额外类型转换),此时对nil调用to_int会直接抛出NoMethodError,程序无法跑完整个流程。 - 计数器状态未随外层迭代重置,计数完全失真
current_counter定义在全局作用域下,每次外层i循环时从未重置为初始值,计数会在之前累加的基础上持续叠加,完全无法对应单次遍历得到的子数组长度。 - 内层循环的起点与外层位置脱节,遍历范围完全错位
每次外层i移动后,内层j始终固定从索引1开始遍历,而非从i的下一个位置向后查找。相当于每次循环都重复比对数组开头的元素,完全无法覆盖i位置之后的元素区间。 - 子数组长度统计存在固定偏差
即便修正了前面的边界、状态、遍历起点问题,当前计数逻辑也只统计了从i位置开始往后、满足差值要求的元素个数,没有把起点位置的a[i]本身计入长度,最终结果会比真实最长长度少1。
最小修复版参考代码
def pickingNumbers(a) a.sort! max_counter = 0 i = 0 while i < a.size # 修正:内层遍历从i的下一位开始 j = i + 1 # 修正:每次外层循环重置当前计数,将起点元素计入长度 current_counter = 1 # 修正:增加索引边界判断,避免越界取到nil while j < a.size && (a[j] - a[i]) <= 1 current_counter += 1 j += 1 max_counter = current_counter if current_counter > max_counter end i += 1 end max_counter end
补充:这种双重循环的实现时间复杂度为O(n²),如果需要更优实现,可以先统计每个数字的出现频次,再遍历所有数字计算「当前数字频次 + 相邻后一个数字频次」的最大值,时间复杂度可降至O(n)。
内容的提问来源于stack exchange,提问作者Sarvar Khalimov
相关产品推荐
相关产品推荐

