📜  大小范围为[L,R]的最大和子数组

📅  最后修改于: 2021-05-17 06:36:08             🧑  作者: Mango

给定一个大小为N的整数数组arr []和两个整数LR。任务是找到大小介于LR之间(包括两端)的最大和子数组。
例子:

方法:

  1. 在这里,我们将使用在这篇文章中讨论的滑动窗口的概念。
  2. 首先计算数组pre []中数组的前缀和。
  3. 接下来在LN -1的范围内进行迭代,并考虑所有大小为LR的子数组。
  4. 创建一个多集以存储子数组长度LR的前缀和。
  5. 现在,要找到以索引i结尾的最大和子数组,只需减去pre [i]和从pre [i – L]pre [i – R]的所有值的最小值。
  6. 最后返回所有金额的最大值。

这是上述方法的实现:

C++
// C++ program to find Maximum sum
// subarray of size between L and R.
 
#include 
using namespace std;
 
// function to find Maximum sum subarray
// of size between L and R
void max_sum_subarray(vector arr,
                      int L, int R)
{
    int n = arr.size();
    int pre[n] = { 0 };
 
    // calculating prefix sum
    pre[0] = arr[0];
    for (int i = 1; i < n; i++) {
        pre[i] = pre[i - 1] + arr[i];
    }
    multiset s1;
 
    // maintain 0 for initial
    // values of i upto R
    // Once i = R, then
    // we need to erase that 0 from
    // our multiset as our first
    // index of subarray
    // cannot be 0 anymore.
    s1.insert(0);
    int ans = INT_MIN;
 
    ans = max(ans, pre[L - 1]);
 
    // we maintain flag to
    // counter if that initial
    // 0 was erased from set or not.
    int flag = 0;
 
    for (int i = L; i < n; i++) {
 
        // erase 0 from multiset once i=b
        if (i - R >= 0) {
            if (flag == 0) {
 
                auto it = s1.find(0);
                s1.erase(it);
                flag = 1;
            }
        }
        // insert pre[i-L]
        if (i - L >= 0)
            s1.insert(pre[i - L]);
 
        // find minimum value in multiset.
        ans = max(ans,
                  pre[i] - *s1.begin());
 
        // erase pre[i-R]
        if (i - R >= 0) {
            auto it = s1.find(pre[i - R]);
            s1.erase(it);
        }
    }
    cout << ans << endl;
}
 
// Driver code
int main()
{
    int L, R;
    L = 1;
    R = 3;
    vector arr = { 1, 2, 2, 1 };
    max_sum_subarray(arr, L, R);
    return 0;
}


Java
// Java program to find Maximum sum
// subarray of size between L and R.
import java.util.*;
class GFG
{
  // function to find Maximum sum subarray
  // of size between L and R
  static void max_sum_subarray(List arr, int L, int R)
  {
    int n = arr.size();
    int[] pre = new int[n];
 
    // calculating prefix sum
    pre[0] = arr.get(0);
    for (int i = 1; i < n; i++)
    {
      pre[i] = pre[i - 1] + arr.get(i);
    }
    List s1 = new ArrayList<>();
 
    // maintain 0 for initial
    // values of i upto R
    // Once i = R, then
    // we need to erase that 0 from
    // our multiset as our first
    // index of subarray
    // cannot be 0 anymore.
    s1.add(0);
    int ans = Integer.MIN_VALUE;
 
    ans = Math.max(ans, pre[L - 1]);
 
    // we maintain flag to
    // counter if that initial
    // 0 was erased from set or not.
    int flag = 0;
 
    for (int i = L; i < n; i++)
    {
 
      // erase 0 from multiset once i=b
      if (i - R >= 0)
      {
        if (flag == 0)
        {
          int it = s1.indexOf(0);
          s1.remove(it);
          flag = 1;
        }
      }
 
      // insert pre[i-L]
      if (i - L >= 0)
        s1.add(pre[i - L]);
 
      // find minimum value in multiset.
      ans = Math.max(ans, pre[i] - s1.get(0));
 
      // erase pre[i-R]
      if (i - R >= 0)
      {
        int it = s1.indexOf(pre[i - R]);
        s1.remove(it);
      }
    }
    System.out.println(ans);
  }
 
  // Driver code
  public static void main(String[] args)
  {
    int L, R;
    L = 1;
    R = 3;
    List arr = Arrays.asList(1, 2, 2, 1);
    max_sum_subarray(arr, L, R); 
  }
}
 
// This code is contributed by divyeshrabadiya07


Python3
# Python3 program to find maximum sum
# subarray of size between L and R.
import sys
 
# Function to find maximum sum subarray
# of size between L and R
def max_sum_subarray(arr, L, R):
 
    n = len(arr)
    pre = n * [0]
 
    # Calculating prefix sum
    pre[0] = arr[0]
    for i in range(1, n):
        pre[i] = pre[i - 1] + arr[i]
 
    s1 = []
 
    # Maintain 0 for initial
    # values of i upto R
    # Once i = R, then
    # we need to erase that 0 from
    # our multiset as our first
    # index of subarray
    # cannot be 0 anymore.
    s1.append(0)
    ans = -sys.maxsize - 1
 
    ans = max(ans, pre[L - 1])
 
    # We maintain flag to
    # counter if that initial
    # 0 was erased from set or not.
    flag = 0
 
    for i in range(L, n):
         
        # Erase 0 from multiset once i=b
        if (i - R >= 0):
            if (flag == 0):
                s1.remove(0)
                flag = 1
     
        # Insert pre[i-L]
        if (i - L >= 0):
            s1.append(pre[i - L])
 
        # Find minimum value in multiset.
        ans = max(ans, pre[i] - s1[0])
 
        # Erase pre[i-R]
        if (i - R >= 0):
            s1.remove(pre[i - R])
 
    print(ans)
 
# Driver code
if __name__ == "__main__":
 
    L = 1
    R = 3
    arr = [ 1, 2, 2, 1 ]
     
    max_sum_subarray(arr, L, R)
 
# This code is contributed by chitranayal


C#
// C# program to find Maximum sum
// subarray of size between L and R.
using System;
using System.Collections.Generic;
class GFG
{
     
    // function to find Maximum sum subarray
    // of size between L and R
    static void max_sum_subarray(List arr, int L, int R)
    {
        int n = arr.Count;
        int[] pre = new int[n];
       
        // calculating prefix sum
        pre[0] = arr[0];
        for (int i = 1; i < n; i++)
        {
            pre[i] = pre[i - 1] + arr[i];
        }
        List s1 = new List();
       
        // maintain 0 for initial
        // values of i upto R
        // Once i = R, then
        // we need to erase that 0 from
        // our multiset as our first
        // index of subarray
        // cannot be 0 anymore.
        s1.Add(0);
        int ans = Int32.MinValue;
       
        ans = Math.Max(ans, pre[L - 1]);
       
        // we maintain flag to
        // counter if that initial
        // 0 was erased from set or not.
        int flag = 0;
       
        for (int i = L; i < n; i++)
        {
       
            // erase 0 from multiset once i=b
            if (i - R >= 0)
            {
                if (flag == 0)
                {
       
                    int it = s1.IndexOf(0);
                    s1.RemoveAt(it);
                    flag = 1;
                }
            }
            // insert pre[i-L]
            if (i - L >= 0)
                s1.Add(pre[i - L]);
       
            // find minimum value in multiset.
            ans = Math.Max(ans, pre[i] - s1[0]);
       
            // erase pre[i-R]
            if (i - R >= 0)
            {
                int it = s1.IndexOf(pre[i - R]);
                s1.RemoveAt(it);
            }
        }
        Console.WriteLine(ans);
    } 
 
  // Driver code
  static void Main()
  {
    int L, R;
    L = 1;
    R = 3;
    List arr = new List(){1, 2, 2, 1};
    max_sum_subarray(arr, L, R);
  }
}
 
// This code is contributed by divyesh072019


输出:
5

时间复杂度: O(N * log N)
辅助空间: O(N)