LeetCode 2090题K半径子数组平均解法报错,请求排查错误
问题分析与解决方案
你的代码在大测试用例(如k=4000、元素多为10000)中失败,主要存在两个核心问题:
1. 整数溢出导致计算错误
Java的int类型取值范围是-2^31到2^31-1(即-2147483648到2147483647)。当k较大时,窗口内元素的总和很容易超出这个范围:
- 比如k=4000时,窗口大小为8001,若每个元素是10000,总和为800110000=80010000,这确实在
int范围内;但如果元素值更大(如题目允许的1e9),总和会达到80011e9=8001000000000,远超int上限,导致temp溢出,最终平均值计算完全错误。
2. 嵌套循环导致超时
当前代码采用嵌套循环,时间复杂度为O(n*k)。当n和k都很大时(比如n=1e5、k=4000),总操作次数会达到4e8次,远超LeetCode的时间限制,直接触发超时错误。
修复后的代码(解决溢出,但仍可能超时)
将存储总和的变量改为long类型,避免溢出问题:
class Solution { public int[] getAverages(int[] nums, int k) { int n = nums.length; int[] avg = new int[n]; int windowSize = 2 * k + 1; for (int i = 0; i < n; i++) { // 简化边界判断:i前后不足k个元素时设为-1 if (i < k || n - i - 1 < k) { avg[i] = -1; } else { long temp = nums[i]; // 用long存储总和,避免溢出 for (int j = 1; j <= k; j++) { temp += nums[i - j] + nums[i + j]; } avg[i] = (int) (temp / windowSize); } } return avg; } }
优化后的滑动窗口解法(解决溢出+超时)
使用滑动窗口思路,将时间复杂度降至O(n),适合大规模数据:
import java.util.Arrays; class Solution { public int[] getAverages(int[] nums, int k) { int n = nums.length; int[] avg = new int[n]; int windowSize = 2 * k + 1; // 初始化所有结果为-1 Arrays.fill(avg, -1); // 如果窗口大小超过数组长度,直接返回全-1 if (windowSize > n) { return avg; } // 计算第一个有效窗口的总和 long sum = 0; for (int i = 0; i < windowSize; i++) { sum += nums[i]; } avg[k] = (int) (sum / windowSize); // 滑动窗口更新后续总和 for (int i = windowSize; i < n; i++) { // 移除窗口左端元素,添加窗口右端新元素 sum = sum - nums[i - windowSize] + nums[i]; // 当前窗口的中心索引是i - k avg[i - k] = (int) (sum / windowSize); } return avg; } }
内容的提问来源于stack exchange,提问作者Kunal Paliwal
相关产品推荐
相关产品推荐

