Java数组最大峰值索引求解:按峰值差值判定的代码修正需求
修正Java数组峰值索引判定逻辑:按峰值与左右元素的最大差值选择
需求说明
在Java数组中找到最大峰值索引,峰值需满足:
- 大于左右相邻元素(首尾元素只需满足单侧大于相邻元素)
- 无峰值则返回-1
- 判定依据为峰值与左右元素的最大差值,而非峰值本身的大小
现有问题代码
原代码仅根据峰值本身大小判定,导致部分测试用例失败:
public int maxPeakIndex(int[] n) { // 变量名错误:参数是n,这里又定义int n,且引用未定义的paymentDelays int n = paymentDelays.length; int maxPeakIndex = -1; int maxPeakValue = Integer.MIN_VALUE; HashMap<Integer, Integer> peakIndices = new HashMap<>(); for (int i = 0; i < n; i++) { int p = n[i]; if ((i == 0 || p > n[i - 1]) && (i == n - 1 || p > n[i + 1])) { if (p > maxPeakValue) { maxPeakValue = p; maxPeakIndex = i; peakIndices.put(maxPeakValue, maxPeakIndex); } else if (p == maxPeakValue) { peakIndices.put(maxPeakValue, i); } } } return maxPeakIndex; }
测试用例情况
失败用例
该用例中代码返回索引1(值18),但正确结果应为索引5(值16,其与左右元素的最大差值更大):
@Test public void maxPeakTest5() { Risk risk = new Risk(); int index = risk.maxPeakIndex(new int[]{17, 18, 17, 1, 0, 16, 0, 0}); Assertions.assertEquals(5, index); }
可正常通过的用例
// 用例1:返回索引7(尾元素,差值3-0=3) int index = risk.maxPeakIndex(new int[]{3, 3, 0, 3, 3, 0, 0, 3}); Assertions.assertEquals(7, index); // 用例2:无峰值,返回-1 int index = risk.maxPeakIndex(new int[]{0, 1, 1, 1, 0, 0, 0, 0}); Assertions.assertEquals(-1, index); // 用例3:返回索引5(值10,最大差值10-0=10) int index = risk.maxPeakIndex(new int[]{5, 4, 2, 2, 0, 10, 8, 3}); Assertions.assertEquals(5, index); // 用例4:返回索引0(值5,差值5-4=1;索引5不是峰值,因为10不大于右侧10) int index = risk.maxPeakIndex(new int[]{5, 4, 2, 2, 0, 10, 10, 3}); Assertions.assertEquals(0, index);
修正思路及代码
核心修改点
- 替换判定指标:计算每个峰值的「最大差值」:
- 首元素(i=0):差值为
n[i] - n[i+1] - 尾元素(i=len-1):差值为
n[i] - n[i-1] - 中间元素:取
n[i]-n[i-1]和n[i]-n[i+1]中的较大值
- 首元素(i=0):差值为
- 跟踪最大差值及对应索引:用
maxDiff记录当前最大差值,maxIndex记录对应索引,遍历峰值时更新这两个变量 - 移除无用代码:原代码中的
peakIndices未被使用,直接删除 - 修复变量名错误:修正参数与局部变量重名的问题,将数组长度变量改为
len
修正后的代码
public int maxPeakIndex(int[] n) { if (n == null || n.length == 0) { return -1; } int len = n.length; int maxIndex = -1; int maxDiff = Integer.MIN_VALUE; for (int i = 0; i < len; i++) { int current = n[i]; boolean isPeak = false; int currentDiff = 0; if (len == 1) { // 单元素数组视为峰值,差值可根据需求调整 isPeak = true; currentDiff = 0; } else if (i == 0) { isPeak = current > n[i + 1]; if (isPeak) { currentDiff = current - n[i + 1]; } } else if (i == len - 1) { isPeak = current > n[i - 1]; if (isPeak) { currentDiff = current - n[i - 1]; } } else { isPeak = current > n[i - 1] && current > n[i + 1]; if (isPeak) { currentDiff = Math.max(current - n[i - 1], current - n[i + 1]); } } if (isPeak) { if (currentDiff > maxDiff) { maxDiff = currentDiff; maxIndex = i; } // 若差值相等,可选择保留第一个或最后一个峰值索引 // 此处示例保留最后一个,如需保留第一个则删除此分支 else if (currentDiff == maxDiff) { maxIndex = i; } } } return maxIndex; }
逻辑验证
针对失败用例[17,18,17,1,0,16,0,0]:
- 索引1(值18):最大差值为
18-17=1 - 索引5(值16):最大差值为
16-0=16
代码会选择索引5作为结果,符合测试预期。
内容的提问来源于stack exchange,提问作者Sergio Domínguez
相关产品推荐
相关产品推荐

