刷题的日常-最大升序子数组和

121 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第10天,点击查看活动详情

刷题的日常-2022年10月7号

一天一题,保持脑子清爽

最大升序子数组和

来自leetcode的 1800 题,题意如下:

给你一个正整数组成的数组 nums ,返回 nums 中一个 升序 子数组的最大可能元素和。

子数组是数组中的一个连续数字序列。

已知子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,若对所有 i(l <= i < r),numsi < numsi+1 都成立,则称这一子数组为 升序 子数组。注意,大小为 1 的子数组也视作 升序 子数组。

示例1:

输入: nums = [10,20,30,5,10,50]
输出: 65
解释: [5,10,50] 是元素和最大的升序子数组,最大元素和为 65 。

示例2:

输入: nums = [10,20,30,40,50]
输出: 150
解释: [10,20,30,40,50] 是元素和最大的升序子数组,最大元素和为 150。

理解题意

我们可以从题意中提取的条件如下:

  • 题目给定一个数组
  • 要求我们统计升序子列表的和的最大值
  • 子列表是连续的
  • 返回其中的最大和

做题思路

简单题,直接遍历一遍就可以解决,我们需要找出每个按升序的子数组,统计它们的和,然后取最大值就可以,但是这里可以用贪心来解决,因为每个连续的子数组是不会交叉的,所以往后遍历,遇到不大于前面的数就进行划分,步骤如下:

  • 开辟两个变量,一个记录前一次的汇总数据,一个记录当前子数组的汇总
  • 遍历数组
  • 如果子数组不连续了,更新变量,否则累加汇总
  • 当前汇总和出现的最大值比较,取其中最大的一个
  • 返回结果即可

代码实现

代码实现如下,因为只需要遍历一次,所以时间复杂度为O(n):

public class Solution {
    public int maxAscendingSum(int[] nums) {
        int pre = nums[0], sum = pre;

        for (int i = 1; i < nums.length; i++) {
            if (nums[i] <= nums[i - 1]) {
                pre = nums[i];
            } else {
                pre += nums[i];
            }
            sum = Math.max(sum, pre);
        }
        return sum;
    }
}

image.png