[leetcode]1749. 任意子数组和的绝对值的最大值(dp)

题目链接

题意

给定一个数组

求任意一个子数组和的绝对值的最大值(子数组可以为空)

方法一

对于最大子段和、最小子段和分别动态规划

最后对abs取max

思路

dpmx[i]表示以nums[i]结尾的子段中最大子段和

dpmn[i]表示以nums[i]结尾的子段中最小子段和

Code

cpp 复制代码
#define pii pair<int,int>
#define ar2 array<int,2>
#define ar3 array<int,3>
#define ar4 array<int,4>
#define endl '\n'
void cmax(int &a,int b){a=max(a,b);};
void cmin(int &a,int b){a=min(a,b);};
const int N=2e5+10,MOD=1e9+7,INF=0x3f3f3f3f;const long long LINF=LLONG_MAX;const double eps=1e-6;
int a[N];

class Solution {
public:
    int maxAbsoluteSum(vector<int>& nums) {
        int n=nums.size();
        vector<int>dpmx(n),dpmn(n);

        int ans=0;

        dpmx[0]=nums[0];

        for(int i=1;i<n;i++){
            dpmx[i]=max(dpmx[i-1],0)+nums[i];
            cmax(ans,dpmx[i]);
        }

        dpmn[0]=nums[0];
        cmax(ans,abs(dpmn[0]));
        for(int i=1;i<n;i++){
            dpmn[i]=min(dpmn[i-1],0)+nums[i];
            cmax(ans,abs(dpmn[i]));
        }

        return ans;

    }
};

实现细节

注意记得ans要跟dpmn的第一个元素取max

空间优化版

cpp 复制代码
#define pii pair<int,int>
#define ar2 array<int,2>
#define ar3 array<int,3>
#define ar4 array<int,4>
#define endl '\n'
void cmax(int &a,int b){a=max(a,b);};
void cmin(int &a,int b){a=min(a,b);};
const int N=2e5+10,MOD=1e9+7,INF=0x3f3f3f3f;const long long LINF=LLONG_MAX;const double eps=1e-6;
int a[N];

class Solution {
public:
    int maxAbsoluteSum(vector<int>& nums) {
        int n=nums.size();

        int ans=abs(nums[0]);

        int f0=nums[0];
        for(int i=1;i<n;i++){
            int nf=max(f0,0)+nums[i];
            cmax(ans,nf);
            f0=nf;
        }
        

        f0=nums[0];
        for(int i=1;i<n;i++){
            int nf=min(f0,0)+nums[i];
            cmax(ans,abs(nf));
            f0=nf;
        }

        return ans;

    }
};

方法二

前缀和 遍历尝试以[1,n-1]每个元素作为子数组结尾的情况 对n个sum取max

思路

对于每个点作为结尾 考虑前面的子段和[0,j]最小或者最大

这样[j+1,i]的子段和就是[0,i]中所有子数组和最大或者最小的

然后对abs取max


这里使用set维护前面的子段和 也可以开一个大根堆和一个小根堆

Code

cpp 复制代码
class Solution {
public:
    int maxAbsoluteSum(vector<int>& nums) {
        int n=nums.size();
        set<int>st;

        int sum=0,ans=0;
        st.emplace(0);
        for(int i=0;i<n;i++){
            sum+=nums[i];
            ans=max({ans,abs(sum-*st.begin()),abs(sum-*st.rbegin())});
            st.emplace(sum);
        }
        return ans;
    }
};
相关推荐
YGGP4 小时前
【Golang】LeetCode 1. 两数之和
leetcode
唐梓航-求职中4 小时前
编程大师-技术-算法-leetcode-355. 设计推特
算法·leetcode·面试
少许极端4 小时前
算法奇妙屋(二十八)-递归、回溯与剪枝的综合问题 1
java·算法·深度优先·剪枝·回溯·递归
仰泳的熊猫4 小时前
题目1453:蓝桥杯历届试题-翻硬币
数据结构·c++·算法·蓝桥杯
唐梓航-求职中4 小时前
技术-算法-leetcode-1606. 找到处理最多请求的服务器(易懂版)
服务器·算法·leetcode
啊阿狸不会拉杆4 小时前
《机器学习导论》第 10 章-线性判别式
人工智能·python·算法·机器学习·numpy·lda·线性判别式
会叫的恐龙4 小时前
C++ 核心知识点汇总(第11日)(排序算法)
c++·算法·排序算法
twilight_4694 小时前
机器学习与模式识别——线性回归算法
算法·机器学习·线性回归
玄同7654 小时前
Python Random 模块深度解析:从基础 API 到 AI / 大模型工程化实践
人工智能·笔记·python·学习·算法·语言模型·llm
Pluchon4 小时前
硅基计划4.0 算法 简单模拟实现位图&布隆过滤器
java·大数据·开发语言·数据结构·算法·哈希算法