zoukankan      html  css  js  c++  java
  • 前缀和的一个应用

    LEETCODE 1031. 两个非重叠子数组的最大和

    给出非负整数数组 A ,返回两个非重叠(连续)子数组中元素的最大和,子数组的长度分别为 L 和 M。(这里需要澄清的是,长为 L 的子数组可以出现在长为 M 的子数组之前或之后。)

    从形式上看,返回最大的 V,而 V = (A[i] + A[i+1] + ... + A[i+L-1]) + (A[j] + A[j+1] + ... + A[j+M-1]) 并满足下列条件之一:

    • 0 <= i < i + L - 1 < j < j + M - 1 < A.length, 或
    • 0 <= j < j + M - 1 < i < i + L - 1 < A.length.

    示例 1:

    输入:A = [0,6,5,2,2,5,1,9,4], L = 1, M = 2
    输出:20
    解释:子数组的一种选择中,[9] 长度为 1,[6,5] 长度为 2。
    

    示例 2:

    输入:A = [3,8,1,3,2,1,8,9,0], L = 3, M = 2
    输出:29
    解释:子数组的一种选择中,[3,8,1] 长度为 3,[8,9] 长度为 2。
    

    示例 3:

    输入:A = [2,1,5,6,0,9,5,0,3,8], L = 4, M = 3
    输出:31
    解释:子数组的一种选择中,[5,6,0,9] 长度为 4,[0,3,8] 长度为 3。

    提示:

    1. L >= 1
    2. M >= 1
    3. L + M <= A.length <= 1000
    4. 0 <= A[i] <= 1000
     1 class Solution {
     2 public:
     3    
     4    int maxSumTwoNoOverlap(vector<int>& A, int L, int M) {
     5     vector<int> preSum(A.size()+1, 0);
     6     for (int i = 1; i <= A.size(); i++) {
     7         preSum[i] = preSum[i - 1] + A[i - 1];
     8     }
     9 
    10     int len = A.size();
    11     int maxSum = 0;
    12     //0~l-1 1~l 2~l+1
    13     for (int i = 0; i < len; i++) {
    14         if (i + L + M - 1 <= len) {
    15             int LSum = preSum[i + L] - preSum[i];
    16             for (int j = i + L; j + M - 1 < len; j++) {
    17                 int RSum = preSum[j + M] - preSum[j];
    18                 if ((RSum + LSum) > maxSum) {
    19                     maxSum = RSum + LSum;
    20                 }
    21             }
    22         }
    23     }
    24 
    25 
    26     for (int i = 0; i < len; i++) {
    27         if (i + L + M - 1 <= len) {
    28             int LSum = preSum[i + M] - preSum[i];
    29             for (int j = i + M; j + L - 1 < len; j++) {
    30                 int RSum = preSum[j + L] - preSum[j];
    31                 if ((RSum + LSum) > maxSum) {
    32                     maxSum = RSum + LSum;
    33                 }
    34             }
    35         }
    36     }
    37 
    38 
    39     return maxSum;
    40 }
    41 };
    View Code

    //=================================================================================

    前缀和
    vector<int> preSum(A.size()+1, 0);
    for (int i = 1; i <= A.size(); i++) {
    preSum[i] = preSum[i - 1] + A[i - 1];
    }


    a[i] a[i+L-1] 的L个数字的和
    就是 preSum[i+L] - preSum[i]

    //===================================================================================

    作 者: itdef
    欢迎转帖 请保持文本完整并注明出处
    技术博客 http://www.cnblogs.com/itdef/
    B站算法视频题解
    https://space.bilibili.com/18508846
    qq 151435887
    gitee https://gitee.com/def/
    欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
    如果觉得不错,欢迎点赞,你的鼓励就是我的动力
    阿里打赏 微信打赏
  • 相关阅读:
    网络动态负载均衡算法分析
    .Net线程问题解答(转)
    Javascript中的类实现(转)
    Log4Net笔记(三)Layout使用以及扩展(转)
    数据结构之排序算法二:堆排序,快速排序,归并排序
    财付通接口(asp)
    数据结构之排序算法一冒泡排序,直接插入排序,简单选择排序
    类与类之间的关系图(Class Diagram,UML图)(转)
    select与epoll
    vnode 和 渲染函数、函数式组件
  • 原文地址:https://www.cnblogs.com/itdef/p/10799784.html
Copyright © 2011-2022 走看看