maxSubArray方法抛出IllegalArgumentException: 6 > 5异常的原因咨询
maxSubArray方法抛出IllegalArgumentException: 6 > 5异常的原因咨询
兄弟,我太懂你这时候的懵圈了——明明6>5是完全合理的逻辑,怎么代码就抛出异常了呢?咱们先把这个问题的本质说清楚:这个异常不是因为你写的6>5的比较逻辑错了,而是Arrays.copyOfRange这个方法有个硬性要求:传入的起始索引必须小于等于结束索引。错误信息里的6>5,其实是说你最后传给这个方法的startIndex是6,而currentIndex + 1是5,6比5大,违反了方法的参数规则,所以才抛出了这个异常。
那为啥会出现startIndex比currentIndex +1还大的情况呢?咱们来扒一扒你代码里的逻辑漏洞:
- 你现在的代码里,只要发现
arr[i] > currentMax + arr[i](也就是当前元素单独成子数组比和前面连起来更大),就直接把startIndex更新成i,但这个startIndex记录的是当前临时子数组的起点,而不是最终全局最大子数组的起点。 - 而
currentIndex只有在currentMax超过max的时候才会更新,也就是说,如果你后来找到的临时子数组(更新了startIndex)的总和没超过之前的全局最大值,那currentIndex就不会跟着更新,最后就会出现startIndex比currentIndex还大的情况,比如你这个数组里,最后startIndex变成了6,currentIndex是4,那currentIndex+1就是5,可不就6>5了嘛。
那怎么修复这个问题呢?核心就是要让startIndex始终对应全局最大子数组的起点,而不是随便一个临时子数组的起点。咱们可以加一个临时变量来跟踪当前临时子数组的起点,只有当这个临时子数组的总和成为新的全局最大值时,再把startIndex同步过去。
修改后的代码是这样的:
public int[] maxSubArray(int[] arr){ if (arr == null || arr.length == 0) { return new int[0]; // 加个空数组判断,避免空指针 } int currentMax = arr[0]; int currentIndex = 0; int max = arr[0]; int startIndex = 0; int tempStartIndex = 0; // 新增临时变量,跟踪当前子数组的起点 for(int i = 1; i < arr.length; i++){ if(arr[i] > currentMax + arr[i]){ tempStartIndex = i; // 临时子数组换起点了,先存在temp里 } currentMax = Math.max(currentMax + arr[i], arr[i]); if (currentMax > max){ currentIndex = i; startIndex = tempStartIndex; // 只有当这个临时子数组成了全局最大,才更新正式的startIndex } max = Math.max(currentMax, max); } return Arrays.copyOfRange(arr, startIndex, currentIndex + 1); }
简单说下修改后的逻辑:
- 用
tempStartIndex来记录当前正在累积的子数组的起点,每次找到新的临时起点就更新它。 - 只有当当前子数组的总和
currentMax超过了全局最大和max时,才说明这个临时起点对应的子数组是新的全局最大子数组,这时候再把startIndex同步成这个临时起点,这样就能保证startIndex和currentIndex始终是一对合法的、对应全局最大子数组的起止索引。
这样调整后,就不会再出现起点大于终点的情况,自然也就不会触发那个让人困惑的异常了。
内容来源于stack exchange
相关产品推荐
相关产品推荐

