NC1——连续子数组最大和(动态规划实现)

题目概述:
给定一个长度为 n 的数组,数组中的数为整数。
请你选择一个非空连续子数组,使该子数组所有数之和尽可能大。求这个最大值。
输入描述:
第一行为一个正整数 n,代表数组的长度。 1<= n <=2*10^5
第二行为 n 个整数 ai,用空格隔开,代表数组中的每一个数。

输出描述:
连续子数组的最大之和。

示例1:

输入:
3
3 -4 5
输出:
5
说明:
选择 [5] 这个子数组即可。

算法思路:
对于该题,想要得到连续子数组的最大和,那么对于当前的元素就要直到该元素之前元素的和是否大于0,此时我们可以定义一个dp数组,用来存储之前元素值和;如果该元素之前元素的和大于等于0,那么在dp数组当前位置就存入dp[i-1]+a[i](其中a数组中存储的是输入的若干个元素);如果dp当前元素之前的元素之和小于0,那么就重新构造子数组,dp当前位置存储的是a[i];
这里需要讨论两个特殊情况
(1)当输入元素第一个就是负数时,那么这个元素就不能包括在子数组当中,因此当前dp数组为dp[0] = 0;
(2)当输入元素都是负数时,那么此时子数组的元素就只能找值最大的那一个负数。

算法实现:

import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
       //获取数组的长度
        Scanner scanner = new Scanner(System.in);
        String str = scanner.nextLine();
        int len = Integer.parseInt(str);
        //定义一个数组用来存储数据
        int[] a = new int[len];
        //获取数组当中的元素
        String str2 = scanner.nextLine();
        String[] strs = str2.split(" ");
        for (int i=0;i<strs.length;i++){
            a[i] = Integer.parseInt(strs[i]);
        }
        //定义数组来存储累加和
        int[] dp = new int[len];
        //如果都是负数
        boolean isFu = true;
        int max1 = Integer.MIN_VALUE;
        for (int i = 0;i<a.length;i++){
            if (a[i]>=0){
                isFu = false;
            }else{
                //如果是负数则找最大值
                max1 = Math.max(max1,a[i]);
            }
            
        }
        if (isFu){
            //表示数组都为负数或0
            System.out.println(max1);
        }else{
            //特殊值:第一位为负数
            if (a[0]>=0){
                dp[0] = a[0];
            }else if (a[0]<0){
                //小于0,那么就不记录第一个
                dp[0] = 0;
            }
            for (int i=1;i<dp.length;i++){
                if (dp[i-1]+a[i]<=0){
                    //如果之前数组累加和小于0,不要
                    dp[i] = 0;
                }else if (dp[i-1]+a[i]>0){
                    dp[i] = dp[i-1]+a[i];
                }
            }
            //得出最大的
            int max = Integer.MIN_VALUE;
            for (int i=0;i<dp.length;i++){
                if (dp[i]>max){
                    max = dp[i];
                }
            }
            System.out.println(max);
        }
    }
}

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值