给定一个大小为N的整数数组arr []和两个整数L和R。任务是找到大小介于L和R之间(包括两端)的最大和子数组。
例子:
Input: arr[] = {1, 2, 2, 1}, L = 1, R = 3
Output: 5
Explaination:
Subarray of size 1 are {1}, {2}, {2}, {1} and maximum sum subarray = 2 for subarray {2}.
Subarray of size 2 are {1, 2}, {2, 2}, {2, 1}, and maximum sum subarray = 4 for subarray {2, 2}.
Subarray of size 3 are {1, 2, 1}, {2, 2, 1}, and maximum sum subarray = 5 for subarray {2, 2, 1}.
Hence the maximum possible sum subarray is 5.
Input: arr[] = {-1, -3, -7, -11}, L = 1, R = 4
Output: -1
方法:
- 在这里,我们将使用在这篇文章中讨论的滑动窗口的概念。
- 首先计算数组pre []中数组的前缀和。
- 接下来在L到N -1的范围内进行迭代,并考虑所有大小为L到R的子数组。
- 创建一个多集以存储子数组长度L到R的前缀和。
- 现在,要找到以索引i结尾的最大和子数组,只需减去pre [i]和从pre [i – L]到pre [i – R]的所有值的最小值。
- 最后返回所有金额的最大值。
这是上述方法的实现:
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)