算法初探LeetCode-任意子数组和的绝对值的最大值

118 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 12 天,点击查看活动详情

LeetCode1749:任意子数组和的绝对值的最大值

给你一个整数数组 nums 。一个子数组 [numsl, numsl+1, ..., numsr-1, numsr] 的 和的绝对值 为 abs(numsl + numsl+1 + ... + numsr-1 + numsr) 。

请你找出 nums 中 和的绝对值 最大的任意子数组(可能为空),并返回该 最大值 。

abs(x) 定义如下:

  • 如果 x 是负整数,那么 abs(x) = -x 。
  • 如果 x 是非负整数,那么 abs(x) = x 。

示例 1:

输入: nums = [1,-3,2,3,-4]
输出: 5
解释: 子数组 [2,3] 和的绝对值最大,为 abs(2+3) = abs(5) = 5

示例 2:

输入: nums = [2,-5,1,-4,3,-2]
输出: 8
解释: 子数组 [-5,1,-4] 和的绝对值最大,为 abs(-5+1-4) = abs(-8) = 8

提示:

  • 1<=nums.length<=1051 <= nums.length <= 10^5
  • 104<=nums[i]<=104-10^4 <= nums[i] <= 10^4

思路分析

在数组或滑动窗口中找到子串和的最大值或最小值的 O(N) 算法 动态规划 dp[i] 表示以nums[i]结尾的子串的最大值或者最小值 以最大值为例 状态转移方程: dp[i] = nums[i] + max(dp[i-1], 0); dp[0] = nums[0]; dp[i]只和dp[i-1]有关,所以可以进行状态压缩,用变量替代dp[i]

分析本题,求任意子数组和的绝对值的最大值等价与求子串和的最大值和最小值,取两者绝对值的最大值

算法代码

public int maxAbsoluteSum(int[] nums) {
    int n = nums.length;
    int max = Integer.MIN_VALUE, sum = 0, min = Integer.MAX_VALUE;

    for (int i = 0; i < n; ++i) {
        sum = nums[i] + Math.max(sum, 0);
        max = Math.max(max, sum);
    }
    sum = 0;
    for (int i = 0; i < n; ++i) {
        sum = nums[i] + Math.min(sum, 0);
        min = Math.min(min, sum);
    }

    max = Math.abs(max);
    min = Math.abs(min);

    return Math.max(max, min);
}

结果详情

Snipaste_2023-02-15_23-17-32.png

算法复杂度

  • 空间复杂度:O(1)O(1)
  • 时间复杂度:O(n)O(n)

掘金(JUEJIN)一起进步,一起成长!