Maximum subarray sum in an array created after repeated concatenation | Set-2
Last Updated :
16 Nov, 2023
Given an array arr[] consisting of N integers and a positive integer K, the task is to find the largest sum of any contiguous subarray in the modified array formed by repeating the given array K times.
Examples:
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
Naive Approach: The simplest approach to solve the problem is discussed in Set-1.
Efficient Approach: The above approach can be optimized further based on the following observations:
- If the sum of the array is greater than 0, then it will contribute to the answer. Otherwise, it is not good to include all array elements into the maximum subarray.
- Suppose variables maxPrefix and maxSufix store the maximum prefix sum and maximum suffix sum of a twice repeated array.
- Therefore, the maximum sum subarray can be formed by either of the following ways:
- Appending the elements of the maxSufix of the array formed by combining the first two arrays, then appending the remaining N-2 arrays.
- First, appending the N-2 arrays and then appending the elements of the maxPrefix of the array formed by combining the last two arrays.
- Taking all the elements of the maximum sum subarray of a twice repeated array.
Follow the steps below to solve the problem:
- Find the sum of the array arr[] and store it in a variable, say sum1.
- Initialize a variable, say sum and ans as 0 to store the current maximum sum and the answer.
- If K = 1, print the maximum subarray sum of the array arr[].
- Otherwise, insert the elements of the array arr[] from [0, N-1] into the array say V[] twice.
- Find the maximum prefix sum of the array V[] and store it in a variable, say maxPrefix.
- Find the maximum suffix sum of the array V[] and store it in a variable, say maxSufix.
- Iterate in the range [0, 2*N-1] using the variable i and perform the following steps:
- Modify the value of sum as max(sum + arr[i], arr[i]) and update the value of ans as max(ans, sum).
- If sum1 > 0, then update ans to the maximum of {ans, sum1*(K-2)+maxPrefix, sum1*(K-2)+maxSufix}.
- Finally, after completing the above steps, print the value of ans as the answer.
Below is the implementation of the above approach:
C++14
// C++ program for the above approach
#include <bits/stdc++.h>
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<int> 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<Integer> V = new ArrayList<Integer>();
// 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
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.
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<int> V = new List<int>();
// 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.
JavaScript
<script>
// JavaScript program for the above approach
// Function to find contiguous subarray with
// maximum sum if array is repeated K times
function maxSubArraySumRepeated(arr, N, K) {
// Store the sum of the array arr[]
let sum = 0;
// Traverse the array and find sum
for (let i = 0; i < N; i++)
sum += arr[i];
let curr = arr[0];
// Store the answer
let ans = arr[0];
// If K = 1
if (K == 1) {
// Apply Kadane algorithm to find sum
for (let 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
let V = [];
// Traverse the range [0, 2*N]
for (let i = 0; i < 2 * N; i++) {
V.push(arr[i % N]);
}
// Stores the maximum suffix sum
let maxSuf = V[0];
// Stores the maximum prefix sum
let maxPref = V[2 * N - 1];
curr = V[0];
for (let i = 1; i < 2 * N; i++) {
curr += V[i];
maxPref = Math.max(maxPref, curr);
}
curr = V[2 * N - 1];
for (let 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 (let 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) {
let temp = sum * (K - 2);
ans = Math.max(ans, Math.max(temp + maxPref, temp + maxSuf));
}
// Return the answer
return ans;
}
// Driver Code
// Given Input
let arr = [10, 20, -30, -1, 40];
let N = arr.length;
let K = 10;
// Function Call
document.write(maxSubArraySumRepeated(arr, N, K));
</script>
Time Complexity: O(N)
Auxiliary Space: O(N)
Another Approach:
- If K==1, use kadane algorithm to find the maximum subarray sum
- Else find the sum of the whole array
- If sum<0, it means after concatenating K more arrays, it will also result in negative value of sum. So, use kadane algorithm after concatenating one more array, which return the sum of maximum suffix from first array and maximum prefix of the second array.
- Else if sum>=0, then we get the maximum subarray sum from maximum of prefix from the last array and maximum of suffix from the first array and the sum of (k-2) arrays i.e. maximum suffix sum(from the first array) + sum*(k-2) + maximum prefix sum(from the last array);
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
//function to find the maximum subarray sum
//kadane algorithm
int kadane(int arr[], int N){
int currsum=0;
int maxsum=INT_MIN;
for(int i=0;i<N;i++){
currsum+=arr[i];
if(currsum<0){
currsum=0;
}
maxsum=max(maxsum, currsum);
}
return maxsum;
}
//after concatenating two arrays,
//apply kadane to it
int twiceKadane(int arr[], int N){
int currsum=0, maxsum=INT_MIN;
for(int i=0;i<2*N;i++){
currsum+= arr[i%N];
if(currsum<0){
currsum=0;
}
maxsum=max(maxsum, currsum);
}
return maxsum;
}
int maxSubArraySumRepeated(int arr[], int N, int K){
//if k==1, normally return kadane
if(K==1){
return kadane(arr, N);
}
long long sum=0;
//find the sum of the whole array
for(int i=0;i<N;i++){
sum+=arr[i];
}
//if sum is negative of the array, then after concatenating the k
//arrays, it will also gives negative sum
//So, the repetitions of 2 arrays will give the result
if(sum<0){
return twiceKadane(arr, N);
}
//if sum>0 or sum=0, then the repetition of the 2 arrays and the
//sum of k-2 arrays will give the result
else{
return twiceKadane(arr, N) + sum*(K-2);
}
}
// 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;
}
//this code is contributed by 525tamannacse1
Java
import java.util.Arrays;
public class GFG {
// Function to find the maximum subarray sum (Kadane's Algorithm)
static int kadane(int[] arr, int N) {
int currSum = 0;
int maxSum = Integer.MIN_VALUE;
for (int i = 0; i < N; i++) {
currSum += arr[i];
if (currSum < 0) {
currSum = 0;
}
maxSum = Math.max(maxSum, currSum);
}
return maxSum;
}
// After concatenating two arrays, apply Kadane's Algorithm to it
static int twiceKadane(int[] arr, int N) {
int currSum = 0;
int maxSum = Integer.MIN_VALUE;
for (int i = 0; i < 2 * N; i++) {
currSum += arr[i % N];
if (currSum < 0) {
currSum = 0;
}
maxSum = Math.max(maxSum, currSum);
}
return maxSum;
}
static int maxSubArraySumRepeated(int[] arr, int N, int K) {
// If K==1, normally return Kadane's result
if (K == 1) {
return kadane(arr, N);
}
long sum = 0;
// Find the sum of the whole array
for (int i = 0; i < N; i++) {
sum += arr[i];
}
// If sum is negative of the array, then after concatenating the K arrays,
// it will also give a negative sum, so the repetitions of 2 arrays will give the result
if (sum < 0) {
return twiceKadane(arr, N);
}
// If sum > 0 or sum = 0, then the repetition of the 2 arrays and the
// sum of (K-2) arrays will give the result
else {
return twiceKadane(arr, N) + (int) (sum * (K - 2));
}
}
// 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.println(maxSubArraySumRepeated(arr, N, K));
}
}
Python
# Function to find the maximum subarray sum (Kadane's Algorithm)
def kadane(arr, N):
currSum = 0
maxSum = float('-inf')
for i in range(N):
currSum += arr[i]
if currSum < 0:
currSum = 0
maxSum = max(maxSum, currSum)
return maxSum
# After concatenating two arrays, apply Kadane's Algorithm to it
def twiceKadane(arr, N):
currSum = 0
maxSum = float('-inf')
for i in range(2 * N):
currSum += arr[i % N]
if currSum < 0:
currSum = 0
maxSum = max(maxSum, currSum)
return maxSum
def maxSubArraySumRepeated(arr, N, K):
# If K == 1, return Kadane's result
if K == 1:
return kadane(arr, N)
sum_val = sum(arr)
# If the sum is negative, repetitions of 2 arrays will give the result
if sum_val < 0:
return twiceKadane(arr, N)
# If sum >= 0, repetitions of 2 arrays and the sum of (K-2) arrays will give the result
else:
return twiceKadane(arr, N) + int(sum_val * (K - 2))
# Given Input
arr = [10, 20, -30, -1, 40]
N = len(arr)
K = 10
# Function Call
print(maxSubArraySumRepeated(arr, N, K))
C#
using System;
class Program {
// Function to find the maximum subarray sum using
// Kadane's algorithm
static int Kadane(int[] arr, int N)
{
int currSum = 0;
int maxSum = int.MinValue;
for (int i = 0; i < N; i++) {
currSum += arr[i];
if (currSum < 0) {
currSum = 0;
}
maxSum = Math.Max(maxSum, currSum);
}
return maxSum;
}
// Function to find the maximum subarray sum after
// repeating the array K times
static int MaxSubArraySumRepeated(int[] arr, int N,
int K)
{
// If K is 1, return the result of a single
// repetition using Kadane's algorithm
if (K == 1) {
return Kadane(arr, N);
}
long sum = 0;
// Find the sum of the whole array
for (int i = 0; i < N; i++) {
sum += arr[i];
}
// If the sum is less than 0, then the result will
// be from repeated 2 arrays
if (sum < 0) {
return TwiceKadane(arr, N);
}
// If the sum is greater than or equal to 0, then
// the result will be from repeated 2 arrays and the
// sum of (K-2) arrays
else {
return TwiceKadane(arr, N)
+ (int)(sum * (K - 2));
}
}
// Function to find the maximum subarray sum after
// repeating the array twice
static int TwiceKadane(int[] arr, int N)
{
int currSum = 0;
int maxSum = int.MinValue;
for (int i = 0; i < 2 * N; i++) {
currSum += arr[i % N];
if (currSum < 0) {
currSum = 0;
}
maxSum = Math.Max(maxSum, currSum);
}
return maxSum;
}
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));
}
}
JavaScript
function kadane(arr, N) {
let currSum = 0;
let maxSum = Number.NEGATIVE_INFINITY;
for (let i = 0; i < N; i++) {
currSum += arr[i];
if (currSum < 0) {
currSum = 0;
}
maxSum = Math.max(maxSum, currSum);
}
return maxSum;
}
// After concatenating two arrays
// apply Kadane's Algorithm to it
function twiceKadane(arr, N) {
let currSum = 0;
let maxSum = Number.NEGATIVE_INFINITY;
for (let i = 0; i < 2 * N; i++) {
currSum += arr[i % N];
if (currSum < 0) {
currSum = 0;
}
maxSum = Math.max(maxSum, currSum);
}
return maxSum;
}
function GFG(arr, N, K) {
// If K==1, normally return Kadane's result
if (K === 1) {
return kadane(arr, N);
}
let sum = 0;
// Find the sum of the whole array
for (let i = 0; i < N; i++) {
sum += arr[i];
}
if (sum < 0) {
return twiceKadane(arr, N);
}
// If sum > 0 or sum = 0, then the repetition of the 2 arrays and
// sum of (K-2) arrays will give the result
else {
return twiceKadane(arr, N) + (sum * (K - 2));
}
}
// Given Input
const arr = [10, 20, -30, -1, 40];
const N = arr.length;
const K = 10;
// Function Call
console.log(GFG(arr, N, K));
Time Complexity: O(N) + O(N) + O(2*N), time complexity of kadane() and maxSubArraySumRepeated() is O(N) as they traverse from 0 to N-1 and the time complexity of twiceKadance() is O(2*N) as it traverse from 0 to 2*N-1.
Space Complexity: O(1)
Similar Reads
Maximum subarray sum in an array created after repeated concatenation
Given an array and a number k, find the largest sum of contiguous array in the modified array which is formed by repeating the given array k times. Examples : Input : arr[] = {-1, 10, 20}, k = 2Output : 59After concatenating array twice, we get {-1, 10, 20, -1, 10, 20} which has maximum subarray sum
4 min read
Maximum Subarray Sum after inverting at most two elements
Given an array arr[] of integer elements, the task is to find maximum possible sub-array sum after changing the signs of at most two elements.Examples: Input: arr[] = {-5, 3, 2, 7, -8, 3, 7, -9, 10, 12, -6} Output: 61 We can get 61 from index 0 to 10 by changing the sign of elements at 4th and 7th i
11 min read
Maximum subarray sum in array formed by repeating the given array k times
Given an integer k and an integer array arr[] of n elements, the task is to find the largest sub-array sum in the modified array (formed by repeating the given array k times). For example, if arr[] = {1, 2} and k = 3 then the modified array will be {1, 2, 1, 2, 1, 2}. Examples: Input: arr[] = {1, 2}
12 min read
Find the maximum sum after dividing array A into M Subarrays
Given a sorted array A[] of size N and an integer M. You need to divide the array A[] into M non-empty consecutive subarray (1 ? M ? N) of any size such that each element is present in exactly one of the M-subarray. After dividing the array A[] into M subarrays you need to calculate the sum [max(i)
10 min read
Maximum subarray sum possible after removing at most K array elements
Given an array arr[] of size N and an integer K, the task is to find the maximum subarray sum by removing at most K elements from the array. Examples: Input: arr[] = { -2, 1, 3, -2, 4, -7, 20 }, K = 1 Output: 26 Explanation: Removing arr[5] from the array modifies arr[] to { -2, 1, 3, -2, 4, 20 } Su
15+ min read
Minimum concatenation required to get strictly LIS for array with repetitive elements | Set-2
Given an array A[] of size n where there can be repetitive elements in the array. We have to find the minimum concatenation required for sequence A to get strictly The Longest Increasing Subsequence. For array A[] we follow 1 based indexing. Examples: Input: A = {2, 1, 2, 4, 3, 5} Output: 2 Explanat
8 min read
Maximum sum obtained by dividing Array into several subarrays as per given conditions
Given an array arr[] of size N, the task is to calculate the maximum sum that can be obtained by dividing the array into several subarrays(possibly one), where each subarray starting at index i and ending at index j (j>=i) contributes arr[j]-arr[i] to the sum. Examples: Input: arr[]= {1, 5, 3}, N
5 min read
Minimum concatenation required to get strictly LIS for the given array
Given an array A[] of size n where there are only unique elements in the array. We have to find the minimum concatenation required for sequence A to get strictly Longest Increasing Subsequence. For array A[] we follow 1 based indexing. Examples: Input: A = {1, 3, 2} Output: 2 Explanation: We can con
6 min read
Maximum sum subarray after altering the array
Given an array arr[] of size N. The task is to find the maximum subarray sum possible after performing the given operation at most once. In a single operation, you can choose any index i and either the subarray arr[0...i] or the subarray arr[i...N-1] can be reversed. Examples: Input: arr[] = {3, 4,
15+ min read
Print all strings corresponding to elements in a subarray with maximum absolute sum
Given an array arr[] consisting of N pairs, each consisting of a string and an integer value corresponding to that string. The task is to find the maximum absolute sum subarray and print the strings corresponding to the elements of the subarray. Examples: Input: arr[] = {("geeks", 4), ("for", -3), (
11 min read