给定大小的两个非重叠子数组的最大和
给定一个数组,我们需要找到两个具有特定长度 K 的子数组,使得这些子数组的总和在所有可能的子数组选择中最大。
例子:
Input : arr[] = [2, 5, 1, 2, 7, 3, 0]
K = 2
Output : 2 5
7 3
We can choose two arrays of maximum sum
as [2, 5] and [7, 3], the sum of these two
subarrays is maximum among all possible
choices of subarrays of length 2.
Input : arr[] = {10, 1, 3, 15, 30, 40, 4, 50, 2, 1}
K = 3
Output : 3 15 30
40 4 50
我们可以解决这个问题,类似于两个指针的方法。首先,我们将前缀和存储在一个单独的数组中,以便可以在恒定时间内计算任何子数组和。之后,我们将从 (N – 2K) 和 (N – K) 索引初始化我们的两个子数组,其中 N 是数组的长度,K 是所需的子数组长度。然后我们将从 (N – 2K) 索引向 0 移动,每次我们将检查当前索引处的子数组总和和 (当前索引 + K) 处的子数组总和是否大于先前选择的子数组,然后更新总和。我们可以在这里看到,由于我们需要最大化我们的总和,我们可以独立处理两个子数组。在每个索引处,我们将检查当前索引处的子数组总和和 K 距离外的子数组总和,我们将独立选择最大总和并将最终答案更新为这两个数组的总和。在下面的代码中,索引也采用一对形式的总和来实际打印子数组。解决方案的总时间复杂度将是线性的。
请参阅下面的代码以更好地理解。
C++
// C++ program to get maximum sum two non-overlapping
// subarrays of same specified length
#include
using namespace std;
// Utility method to get sum of subarray
// from index i to j
int getSubarraySum(int sum[], int i, int j)
{
if (i == 0)
return sum[j];
else
return (sum[j] - sum[i - 1]);
}
// Method prints two non-overlapping subarrays of
// length K whose sum is maximum
void maximumSumTwoNonOverlappingSubarray(int arr[],
int N, int K)
{
int sum[N];
// filling prefix sum array
sum[0] = arr[0];
for (int i = 1; i < N; i++)
sum[i] = sum[i - 1] + arr[i];
// initializing subarrays from (N-2K) and (N-K) indices
pair resIndex = make_pair(N - 2 * K, N - K);
// initializing result sum from above subarray sums
int maxSum2Subarray = getSubarraySum(sum, N - 2 * K, N - K - 1) +
getSubarraySum(sum, N - K, N - 1);
// storing second subarray maximum and its starting index
pair secondSubarrayMax = make_pair(N - K,
getSubarraySum(sum, N - K, N - 1));
// looping from N-2K-1 towards 0
for (int i = N - 2 * K - 1; i >= 0; i--)
{
// get subarray sum from (current index + K)
int cur = getSubarraySum(sum, i + K, i + 2 * K - 1);
// if (current index + K) sum is more then update
// secondSubarrayMax
if (cur >= secondSubarrayMax.second)
secondSubarrayMax = make_pair(i + K, cur);
// now getting complete sum (sum of both subarrays)
cur = getSubarraySum(sum, i, i + K - 1) +
secondSubarrayMax.second;
// if it is more then update main result
if (cur >= maxSum2Subarray)
{
maxSum2Subarray = cur;
resIndex = make_pair(i, secondSubarrayMax.first);
}
}
// printing actual subarrays
for (int i = resIndex.first; i < resIndex.first + K; i++)
cout << arr[i] << " ";
cout << endl;
for (int i = resIndex.second; i < resIndex.second + K; i++)
cout << arr[i] << " ";
cout << endl;
}
// Driver code to test above methods
int main()
{
int arr[] = {2, 5, 1, 2, 7, 3, 0};
int N = sizeof(arr) / sizeof(int);
// K will be given such that (N >= 2K)
int K = 2;
maximumSumTwoNonOverlappingSubarray(arr, N, K);
return 0;
}
Java
// Java program to get maximum sum two non-overlapping
// subarrays of same specified length
class GFG
{
static class pair
{
int first, second;
public pair(int first, int second)
{
this.first = first;
this.second = second;
}
}
// Utility method to get sum of subarray
// from index i to j
static int getSubarraySum(int sum[],
int i, int j)
{
if (i == 0)
return sum[j];
else
return (sum[j] - sum[i - 1]);
}
// Method prints two non-overlapping subarrays of
// length K whose sum is maximum
static void maximumSumTwoNonOverlappingSubarray(int arr[],
int N, int K)
{
int []sum = new int[N];
// filling prefix sum array
sum[0] = arr[0];
for (int i = 1; i < N; i++)
sum[i] = sum[i - 1] + arr[i];
// initializing subarrays from
// (N-2K) and (N-K) indices
pair resIndex = new pair(N - 2 * K, N - K);
// initializing result sum from above subarray sums
int maxSum2Subarray = getSubarraySum(sum, N - 2 * K,
N - K - 1) +
getSubarraySum(sum, N - K, N - 1);
// storing second subarray maximum and
// its starting index
pair secondSubarrayMax = new pair(N - K,
getSubarraySum(sum, N - K, N - 1));
// looping from N-2K-1 towards 0
for (int i = N - 2 * K - 1; i >= 0; i--)
{
// get subarray sum from (current index + K)
int cur = getSubarraySum(sum, i + K, i + 2 * K - 1);
// if (current index + K) sum is more
// then update secondSubarrayMax
if (cur >= secondSubarrayMax.second)
secondSubarrayMax = new pair(i + K, cur);
// now getting complete sum (sum of both subarrays)
cur = getSubarraySum(sum, i, i + K - 1) +
secondSubarrayMax.second;
// if it is more then update main result
if (cur >= maxSum2Subarray)
{
maxSum2Subarray = cur;
resIndex = new pair(i, secondSubarrayMax.first);
}
}
// printing actual subarrays
for (int i = resIndex.first;
i < resIndex.first + K; i++)
System.out.print(arr[i] + " ");
System.out.println();
for (int i = resIndex.second;
i < resIndex.second + K; i++)
System.out.print(arr[i] + " ");
System.out.println();
}
// Driver code to test above methods
public static void main(String[] args)
{
int arr[] = {2, 5, 1, 2, 7, 3, 0};
int N = arr.length;
// K will be given such that (N >= 2K)
int K = 2;
maximumSumTwoNonOverlappingSubarray(arr, N, K);
}
}
// This code is contributed by Rajput-Ji
Python3
# Python3 program to get maximum Sum two
# non-overlapping subarrays of same specified length
# Utility method to get Sum of
# subarray from index i to j
def getSubarraySum(Sum, i, j):
if i == 0:
return Sum[j]
else:
return Sum[j] - Sum[i - 1]
# Method prints two non-overlapping subarrays
# of length K whose Sum is maximum
def maximumSumTwoNonOverlappingSubarray(arr, N, K):
Sum = [None] * N
# filling prefix Sum array
Sum[0] = arr[0]
for i in range(1, N):
Sum[i] = Sum[i - 1] + arr[i]
# Initializing subarrays from
# (N-2K) and (N-K) indices
resIndex = (N - 2 * K, N - K)
# initializing result Sum from above subarray Sums
maxSum2Subarray = (getSubarraySum(Sum, N - 2 * K, N - K - 1) +
getSubarraySum(Sum, N - K, N - 1))
# storing second subarray maximum and its starting index
secondSubarrayMax = (N - K, getSubarraySum(Sum, N - K, N - 1))
# looping from N-2K-1 towards 0
for i in range(N - 2 * K - 1, -1, -1):
# get subarray Sum from (current index + K)
cur = getSubarraySum(Sum, i + K, i + 2 * K - 1)
# if (current index + K) Sum is more
# than update secondSubarrayMax
if cur >= secondSubarrayMax[1]:
secondSubarrayMax = (i + K, cur)
# now getting complete Sum (Sum of both subarrays)
cur = (getSubarraySum(Sum, i, i + K - 1) +
secondSubarrayMax[1])
# If it is more then update main result
if cur >= maxSum2Subarray:
maxSum2Subarray = cur
resIndex = (i, secondSubarrayMax[0])
# printing actual subarrays
for i in range(resIndex[0], resIndex[0] + K):
print(arr[i], end = " ")
print()
for i in range(resIndex[1], resIndex[1] + K):
print(arr[i], end = " ")
print()
# Driver Code
if __name__ == "__main__":
arr = [2, 5, 1, 2, 7, 3, 0]
N = len(arr)
# K will be given such that (N >= 2K)
K = 2
maximumSumTwoNonOverlappingSubarray(arr, N, K)
# This code is contributed by Rituraj Jain
C#
// C# program to get maximum sum two non-overlapping
// subarrays of same specified length
using System;
class GFG
{
class pair
{
public int first, second;
public pair(int first, int second)
{
this.first = first;
this.second = second;
}
}
// Utility method to get sum of subarray
// from index i to j
static int getSubarraySum(int []sum,
int i, int j)
{
if (i == 0)
return sum[j];
else
return (sum[j] - sum[i - 1]);
}
// Method prints two non-overlapping subarrays of
// length K whose sum is maximum
static void maximumSumTwoNonOverlappingSubarray(int []arr,
int N, int K)
{
int []sum = new int[N];
// filling prefix sum array
sum[0] = arr[0];
for (int i = 1; i < N; i++)
sum[i] = sum[i - 1] + arr[i];
// initializing subarrays from
// (N-2K) and (N-K) indices
pair resIndex = new pair(N - 2 * K, N - K);
// initializing result sum from above subarray sums
int maxSum2Subarray = getSubarraySum(sum, N - 2 * K,
N - K - 1) +
getSubarraySum(sum, N - K, N - 1);
// storing second subarray maximum and
// its starting index
pair secondSubarrayMax = new pair(N - K,
getSubarraySum(sum, N - K, N - 1));
// looping from N-2K-1 towards 0
for (int i = N - 2 * K - 1; i >= 0; i--)
{
// get subarray sum from (current index + K)
int cur = getSubarraySum(sum, i + K, i + 2 * K - 1);
// if (current index + K) sum is more
// then update secondSubarrayMax
if (cur >= secondSubarrayMax.second)
secondSubarrayMax = new pair(i + K, cur);
// now getting complete sum (sum of both subarrays)
cur = getSubarraySum(sum, i, i + K - 1) +
secondSubarrayMax.second;
// if it is more then update main result
if (cur >= maxSum2Subarray)
{
maxSum2Subarray = cur;
resIndex = new pair(i, secondSubarrayMax.first);
}
}
// printing actual subarrays
for (int i = resIndex.first;
i < resIndex.first + K; i++)
Console.Write(arr[i] + " ");
Console.WriteLine();
for (int i = resIndex.second;
i < resIndex.second + K; i++)
Console.Write(arr[i] + " ");
Console.WriteLine();
}
// Driver code
public static void Main(String[] args)
{
int []arr = {2, 5, 1, 2, 7, 3, 0};
int N = arr.Length;
// K will be given such that (N >= 2K)
int K = 2;
maximumSumTwoNonOverlappingSubarray(arr, N, K);
}
}
// This code is contributed by 29AjayKumar
Javascript
输出:
2 5
7 3