重复连接后创建的数组中的最大子数组和 |第 2 组
给定一个数组 arr[]由N个整数和一个正整数K组成,任务是在通过重复给定数组K次形成的修改数组中找到任何连续子数组的最大和。
例子:
Input: arr[] = {-1, 10, 20}, K = 2
Output: 59
Explanation:
After concatenating the array twice, the array modifies to {-1, 10, 20, -1, 10, 20}.
The subarray with the maximum sum is over the range [1, 5] i.e {10, 20, -1, 10, 20}.
Input: arr[] = {10, 20, -30, -1, 40}, K =10
Output: 391
朴素方法:解决问题的最简单方法在 Set-1 中讨论。
有效的方法:上述方法可以根据以下观察进一步优化:
- 如果数组的总和大于0 ,那么它将有助于答案。否则,将所有数组元素都包含在最大子数组中是不好的。
- 假设变量maxPrefix和maxSufix存储了两次重复数组的最大前缀和和最大后缀和。
- 因此,最大和子数组可以通过以下两种方式之一形成:
- 附加由组合前两个数组形成的数组的maxSufix的元素,然后附加剩余的N-2 个数组。
- 首先追加N-2个数组,然后追加组合最后两个数组形成的数组的maxPrefix的元素。
- 取两次重复数组的最大和子数组的所有元素。
请按照以下步骤解决问题:
- 找到数组arr[]的总和并将其存储在一个变量中,比如sum1 。
- 初始化一个变量,比如sum和ans为0以存储当前最大和和答案。
- 如果K = 1 ,则打印数组arr[] 的最大子数组和。
- 否则,将数组arr[]的元素从[0, N-1]插入到数组V[]中两次。
- 找到数组V[]的最大前缀和并将其存储在一个变量中,比如maxPrefix 。
- 找到数组V[]的最大后缀和并将其存储在一个变量中,比如maxSufix 。
- 使用变量i在[0, 2*N-1]范围内迭代并执行以下步骤:
- 将sum的值修改为max(sum + arr[i], arr[i]) ,将ans的值更新为max(ans, sum)。
- 如果sum1 > 0,则将ans更新为{ans, sum1*(K-2)+maxPrefix, sum1*(K-2)*maxSufix} 的最大值。
- 最后,完成以上步骤后,打印ans的值作为答案。
下面是上述方法的实现:
C++14
// C++ program for the above approach
#include
using namespace std;
// Function to find contiguous subarray with
// maximum sum if array is repeated K times
int maxSubArraySumRepeated(int arr[], int N, int K)
{
// Store the sum of the array arr[]
int sum = 0;
// Traverse the array and find sum
for (int i = 0; i < N; i++)
sum += arr[i];
int curr = arr[0];
// Store the answer
int ans = arr[0];
// If K = 1
if (K == 1) {
// Apply Kadane algorithm to find sum
for (int i = 1; i < N; i++) {
curr = max(arr[i], curr + arr[i]);
ans = max(ans, curr);
}
// Return the answer
return ans;
}
// Stores the twice repeated array
vector V;
// Traverse the range [0, 2*N]
for (int i = 0; i < 2 * N; i++) {
V.push_back(arr[i % N]);
}
// Stores the maximum suffix sum
int maxSuf = V[0];
// Stores the maximum prefix sum
int maxPref = V[2 * N - 1];
curr = V[0];
for (int i = 1; i < 2 * N; i++) {
curr += V[i];
maxPref = max(maxPref, curr);
}
curr = V[2 * N - 1];
for (int i = 2 * N - 2; i >= 0; i--) {
curr += V[i];
maxSuf = max(maxSuf, curr);
}
curr = V[0];
// Apply Kadane algorithm for 2 repetition
// of the array
for (int i = 1; i < 2 * N; i++) {
curr = max(V[i], curr + V[i]);
ans = max(ans, curr);
}
// If the sum of the array is greater than 0
if (sum > 0) {
int temp = 1LL * sum * (K - 2);
ans = max(ans, max(temp + maxPref, temp + maxSuf));
}
// Return the answer
return ans;
}
// Driver Code
int main()
{
// Given Input
int arr[] = { 10, 20, -30, -1, 40 };
int N = sizeof(arr) / sizeof(arr[0]);
int K = 10;
// Function Call
cout << maxSubArraySumRepeated(arr, N, K);
return 0;
}
Java
// Java program for the above approach
import java.util.*;
class GFG{
// Function to find contiguous subarray with
// maximum sum if array is repeated K times
static int maxSubArraySumRepeated(int[] arr, int N,
int K)
{
// Store the sum of the array arr[]
int sum = 0;
// Traverse the array and find sum
for(int i = 0; i < N; i++)
sum += arr[i];
int curr = arr[0];
// Store the answer
int ans = arr[0];
// If K = 1
if (K == 1)
{
// Apply Kadane algorithm to find sum
for(int i = 1; i < N; i++)
{
curr = Math.max(arr[i], curr + arr[i]);
ans = Math.max(ans, curr);
}
// Return the answer
return ans;
}
// Stores the twice repeated array
ArrayList V = new ArrayList();
// Traverse the range [0, 2*N]
for(int i = 0; i < 2 * N; i++)
{
V.add(arr[i % N]);
}
// Stores the maximum suffix sum
int maxSuf = V.get(0);
// Stores the maximum prefix sum
int maxPref = V.get(2 * N - 1);
curr = V.get(0);
for(int i = 1; i < 2 * N; i++)
{
curr += V.get(i);
maxPref = Math.max(maxPref, curr);
}
curr = V.get(2 * N - 1);
for(int i = 2 * N - 2; i >= 0; i--)
{
curr += V.get(i);
maxSuf = Math.max(maxSuf, curr);
}
curr = V.get(0);
// Apply Kadane algorithm for 2 repetition
// of the array
for(int i = 1; i < 2 * N; i++)
{
curr = Math.max(V.get(i), curr + V.get(i));
ans = Math.max(ans, curr);
}
// If the sum of the array is greater than 0
if (sum > 0)
{
int temp = sum * (K - 2);
ans = Math.max(ans, Math.max(temp + maxPref,
temp + maxSuf));
}
// Return the answer
return ans;
}
// Driver Code
public static void main(String args[])
{
// Given Input
int []arr = { 10, 20, -30, -1, 40 };
int N = arr.length;
int K = 10;
// Function Call
System.out.print(maxSubArraySumRepeated(arr, N, K));
}
}
// This code is contributed by SURENDRA_GANGWAR
C#
// C# program for the above approach
using System;
using System.Collections.Generic;
class GFG {
// Function to find contiguous subarray with
// maximum sum if array is repeated K times
static int maxSubArraySumRepeated(int[] arr, int N,
int K)
{
// Store the sum of the array arr[]
int sum = 0;
// Traverse the array and find sum
for (int i = 0; i < N; i++)
sum += arr[i];
int curr = arr[0];
// Store the answer
int ans = arr[0];
// If K = 1
if (K == 1) {
// Apply Kadane algorithm to find sum
for (int i = 1; i < N; i++) {
curr = Math.Max(arr[i], curr + arr[i]);
ans = Math.Max(ans, curr);
}
// Return the answer
return ans;
}
// Stores the twice repeated array
List V = new List();
// Traverse the range [0, 2*N]
for (int i = 0; i < 2 * N; i++) {
V.Add(arr[i % N]);
}
// Stores the maximum suffix sum
int maxSuf = V[0];
// Stores the maximum prefix sum
int maxPref = V[2 * N - 1];
curr = V[0];
for (int i = 1; i < 2 * N; i++) {
curr += V[i];
maxPref = Math.Max(maxPref, curr);
}
curr = V[2 * N - 1];
for (int i = 2 * N - 2; i >= 0; i--) {
curr += V[i];
maxSuf = Math.Max(maxSuf, curr);
}
curr = V[0];
// Apply Kadane algorithm for 2 repetition
// of the array
for (int i = 1; i < 2 * N; i++) {
curr = Math.Max(V[i], curr + V[i]);
ans = Math.Max(ans, curr);
}
// If the sum of the array is greater than 0
if (sum > 0) {
int temp = sum * (K - 2);
ans = Math.Max(ans, Math.Max(temp + maxPref,
temp + maxSuf));
}
// Return the answer
return ans;
}
// Driver Code
public static void Main()
{
// Given Input
int[] arr = { 10, 20, -30, -1, 40 };
int N = arr.Length;
int K = 10;
// Function Call
Console.WriteLine(
maxSubArraySumRepeated(arr, N, K));
}
}
// This code is contributed by ukasp.
Python3
# python 3 program for the above approach
# Function to find contiguous subarray with
# maximum sum if array is repeated K times
def maxSubArraySumRepeated(arr, N, K):
# Store the sum of the array arr[]
sum = 0
# Traverse the array and find sum
for i in range(N):
sum += arr[i]
curr = arr[0]
# Store the answer
ans = arr[0]
# If K = 1
if (K == 1):
# Apply Kadane algorithm to find sum
for i in range(1,N,1):
curr = max(arr[i], curr + arr[i])
ans = max(ans, curr)
# Return the answer
return ans
# Stores the twice repeated array
V = []
# Traverse the range [0, 2*N]
for i in range(2 * N):
V.append(arr[i % N])
# Stores the maximum suffix sum
maxSuf = V[0]
# Stores the maximum prefix sum
maxPref = V[2 * N - 1]
curr = V[0]
for i in range(1,2 * N,1):
curr += V[i]
maxPref = max(maxPref, curr)
curr = V[2 * N - 1]
i = 2 * N - 2
while(i >= 0):
curr += V[i]
maxSuf = max(maxSuf, curr)
i -= 1
curr = V[0]
# Apply Kadane algorithm for 2 repetition
# of the array
for i in range(1, 2 * N, 1):
curr = max(V[i], curr + V[i])
ans = max(ans, curr)
# If the sum of the array is greater than 0
if (sum > 0):
temp = sum * (K - 2)
ans = max(ans, max(temp + maxPref, temp + maxSuf))
# Return the answer
return ans
# Driver Code
if __name__ == '__main__':
# Given Input
arr = [10, 20, -30, -1, 40]
N = len(arr)
K = 10
# Function Call
print(maxSubArraySumRepeated(arr, N, K))
# This code is contributed by ipg2016107.
Javascript
输出
391
时间复杂度: O(N)
辅助空间: O(N)