You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修正Java最大和子序列代码,优先返回首个等长等和序列?

最大和子序列问题修复

问题说明

我编写了一个Java程序用于寻找元素和最大的子序列,规则如下:

  • 若存在多个和相同但元素数量不同的序列,输出元素最少的
  • 若存在2个及以上和相同且元素数量相同的序列,需返回列表中最先出现的序列

但当前程序返回的是最后一个符合条件的序列,预期输出为100 98,实际输出为99 99。

原代码

import java.util.ArrayList;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(-9999);
        list.add(-9999);
        list.add(100);//索引4
        list.add(98);//索引5
        list.add(-5555);
        list.add(99);
        list.add(99);
        list.add(-7866);
        list.add(6);
        list.add(-3);
        list.add(-13434);
        list.add(99);//索引13
        list.add(90);
        list.add(8);
        list.add(1);//索引16
        list.add(-9999);
        //list.add(99);//11
        //list.add(99);//12
        list.add(-9999);
        //list.add(198);
        list.add(-444);
        list.add(-7444);
        list.add(100);
        list.add(90);
        list.add(8);
        list.add(-9999);
        //list.add(100);
        //list.add(98);
        list.add(-5555);
        
        if (list == null || list.size() == 0) {//检查列表是否为空
            System.out.println("empty array");
            return;
        }

        int maxSumStartIndex = 0;
        int maxSumLastIndex = 0;
        int maxSum = list.get(0);

        int lastSumStartIndex = 0;
        int lastSum = list.get(0);

        for (int i = 1; i < list.size(); i++) {

            lastSum += list.get(i);
            if (lastSum < list.get(i)) {
                lastSum = list.get(i);
                lastSumStartIndex = i;
            }

            if (maxSum < lastSum) {
                maxSumStartIndex = lastSumStartIndex;
                maxSumLastIndex = i;
                maxSum = lastSum;
            }
            if (maxSum == lastSum) {
                if (maxSumLastIndex - maxSumStartIndex < i - lastSumStartIndex) continue;//用于保留最短长度
                maxSumStartIndex = lastSumStartIndex;
                maxSumLastIndex = i;
            }
        }

        System.out.println("sum( arr[" + maxSumStartIndex + "] .. arr[" + maxSumLastIndex + "] ) = " + maxSum);
        for (int i = maxSumStartIndex; i <= maxSumLastIndex; i++) {
            System.out.print(list.get(i) + " ");
        }
    }
}

问题根源

原代码在处理和相同的序列时,判断逻辑错误:只要新序列的长度不小于当前最大序列的长度,就会更新最大序列的索引。这导致后续出现的同长度同和序列会覆盖掉之前最先出现的序列。

修复方案

修改maxSum == lastSum的判断逻辑,仅当新序列的长度更短时才更新最大序列;若长度相同,则保留最先出现的序列,不做更新。

修复后的关键代码块:

if (maxSum == lastSum) {
    int currentSeqLength = maxSumLastIndex - maxSumStartIndex + 1;
    int newSeqLength = i - lastSumStartIndex + 1;
    // 仅当新序列长度更短时才更新,长度相同则保留最早出现的序列
    if (newSeqLength < currentSeqLength) {
        maxSumStartIndex = lastSumStartIndex;
        maxSumLastIndex = i;
    }
}

修复后完整代码

import java.util.ArrayList;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(-9999);
        list.add(-9999);
        list.add(100);//索引4
        list.add(98);//索引5
        list.add(-5555);
        list.add(99);
        list.add(99);
        list.add(-7866);
        list.add(6);
        list.add(-3);
        list.add(-13434);
        list.add(99);//索引13
        list.add(90);
        list.add(8);
        list.add(1);//索引16
        list.add(-9999);
        //list.add(99);//11
        //list.add(99);//12
        list.add(-9999);
        //list.add(198);
        list.add(-444);
        list.add(-7444);
        list.add(100);
        list.add(90);
        list.add(8);
        list.add(-9999);
        //list.add(100);
        //list.add(98);
        list.add(-5555);
        
        if (list == null || list.size() == 0) {//检查列表是否为空
            System.out.println("empty array");
            return;
        }

        int maxSumStartIndex = 0;
        int maxSumLastIndex = 0;
        int maxSum = list.get(0);

        int lastSumStartIndex = 0;
        int lastSum = list.get(0);

        for (int i = 1; i < list.size(); i++) {

            lastSum += list.get(i);
            if (lastSum < list.get(i)) {
                lastSum = list.get(i);
                lastSumStartIndex = i;
            }

            if (maxSum < lastSum) {
                maxSumStartIndex = lastSumStartIndex;
                maxSumLastIndex = i;
                maxSum = lastSum;
            }
            if (maxSum == lastSum) {
                int currentSeqLength = maxSumLastIndex - maxSumStartIndex + 1;
                int newSeqLength = i - lastSumStartIndex + 1;
                // 仅当新序列长度更短时才更新,长度相同则保留最早出现的序列
                if (newSeqLength < currentSeqLength) {
                    maxSumStartIndex = lastSumStartIndex;
                    maxSumLastIndex = i;
                }
            }
        }

        System.out.println("sum( arr[" + maxSumStartIndex + "] .. arr[" + maxSumLastIndex + "] ) = " + maxSum);
        for (int i = maxSumStartIndex; i <= maxSumLastIndex; i++) {
            System.out.print(list.get(i) + " ");
        }
    }
}

验证结果

修复后程序会输出预期的100 98,符合规则中“同和同长度时返回最先出现序列”的要求。

内容的提问来源于stack exchange,提问作者vegaLDN

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 01:15:52