Find maximum value of Sum( i*arr[i]) with only rotations on given array allowed
Given an array arr[] of size N, the task is to find the maximum possible sum of i*arr[i] when the array can be rotated any number of times.
Examples :
Input: arr[] = {1, 20, 2, 10}
Output: 72.We can get 72 by rotating array twice.
{2, 10, 1, 20}
20*3 + 1*2 + 10*1 + 2*0 = 72
Input: arr[] = {10, 1, 2, 3, 4, 5, 6, 7, 8, 9}
Output: 330
We can get 330 by rotating array 9 times.
{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
0*1 + 1*2 + 2*3 … 9*10 = 330
Naive Approach: The basic idea of this approach is
Find all rotations one by one, check the sum of every rotation and return the maximum sum.
Algorithm
- Start by initializing max_sum to INT_MIN
- Loop say i,from 0 to n-1:
- a. Initialize sum to 0
- b. Loop j from 0 to n-1:
- i. Calculate the index of the j-th element after rotation: (i+j) % n
- ii. Add the product of the element and its index to sum: j * arr[(i+j) % n]
- c. If sum is greater than max_sum, update max_sum to sum
- Return max_sum
C++
#include <climits>
#include <iostream>
using namespace std;
int max_sum_rotation( int arr[], int n)
{
int max_sum = INT_MIN;
for ( int i = 0; i < n;
i++) {
int sum = 0;
for ( int j = 0; j < n;
j++) {
int index
= (i + j)
% n;
sum += j * arr[index];
}
max_sum = max(
max_sum,
sum);
}
return max_sum;
}
int main()
{
int arr[] = {
10, 1, 2, 3, 4, 5, 6, 7, 8, 9
};
int n = sizeof (arr)
/ sizeof (
arr[0]);
cout << max_sum_rotation(arr, n)
<< endl;
return 0;
}
|
Java
import java.io.*;
public class MaxSumRotation {
public static int maxSumRotation( int [] arr, int n) {
int maxSum = Integer.MIN_VALUE;
for ( int i = 0 ; i < n; i++) {
int sum = 0 ;
for ( int j = 0 ; j < n; j++) {
int index = (i + j) % n;
sum += j * arr[index];
}
maxSum = Math.max(maxSum, sum);
}
return maxSum;
}
public static void main(String[] args) {
int [] arr = { 10 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 };
int n = arr.length;
System.out.println(maxSumRotation(arr, n));
}
}
|
Python3
def max_sum_rotation(arr, n):
max_sum = float ( '-inf' )
for i in range (n):
sum = 0
for j in range (n):
index = (i + j) % n
sum + = j * arr[index]
max_sum = max (max_sum, sum )
return max_sum
arr = [ 10 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ]
n = len (arr)
print (max_sum_rotation(arr, n))
|
C#
using System;
class Program
{
static int MaxSumRotation( int [] arr, int n)
{
int maxSum = int .MinValue;
for ( int i = 0; i < n; i++)
{
int sum = 0;
for ( int j = 0; j < n; j++)
{
int index = (i + j) % n;
sum += j * arr[index];
}
maxSum = Math.Max(maxSum, sum);
}
return maxSum;
}
static void Main( string [] args)
{
int [] arr = { 10, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int n = arr.Length;
Console.WriteLine(MaxSumRotation(arr, n));
}
}
|
Javascript
function maxSumRotation(arr) {
const n = arr.length;
let maxSum = Number.MIN_SAFE_INTEGER;
for (let i = 0; i < n; i++) {
let sum = 0;
for (let j = 0; j < n; j++) {
const index = (i + j) % n;
sum += j * arr[index];
}
maxSum = Math.max(maxSum, sum);
}
return maxSum;
}
const arr = [10, 1, 2, 3, 4, 5, 6, 7, 8, 9];
console.log(maxSumRotation(arr));
|
Time Complexity: O(N2), where n is the size of the input array.
Auxiliary Space: O(1), because it uses a constant amount of extra space to store the variables max_sum, sum, i, and j.
Efficient Approach: The idea is as follows:
Let Rj be value of i*arr[i] with j rotations.
- The idea is to calculate the next rotation value from the previous rotation, i.e., calculate Rj from Rj-1.
- We can calculate the initial value of the result as R0, then keep calculating the next rotation values.
How to efficiently calculate Rj from Rj-1?
This can be done in O(1) time. Below are the details.
Let us calculate initial value of i*arr[i] with no rotation
R0 = 0*arr[0] + 1*arr[1] +…+ (n-1)*arr[n-1]
After 1 rotation arr[n-1], becomes first element of array,
- arr[0] becomes second element, arr[1] becomes third element and so on.
- R1 = 0*arr[n-1] + 1*arr[0] +…+ (n-1)*arr[n-2]
- R1 – R0 = arr[0] + arr[1] + … + arr[n-2] – (n-1)*arr[n-1]
After 2 rotations arr[n-2], becomes first element of array,
- arr[n-1] becomes second element, arr[0] becomes third element and so on.
- R2 = 0*arr[n-2] + 1*arr[n-1] +…+ (n-1)*arr[n-3]
- R2 – R1 = arr[0] + arr[1] + … + arr[n-3] – (n-1)*arr[n-2] + arr[n-1]
If we take a closer look at above values, we can observe below pattern
Rj – Rj-1 = arrSum – n * arr[n-j],
Where arrSum is sum of all array elements, i.e., arrSum = ∑ arr[i] , 0 ≤ i ≤ N-1
Follow the below illustration for a better understanding.
Illustration:
Given arr[]={10, 1, 2, 3, 4, 5, 6, 7, 8, 9},
arrSum = 55, currVal = summation of (i*arr[i]) = 285
In each iteration the currVal is currVal = currVal + arrSum-n*arr[n-j] ,
1st rotation: currVal = 285 + 55 – (10 * 9) = 250
2nd rotation: currVal = 250 + 55 – (10 * 8) = 225
3rd rotation: currVal = 225 + 55 – (10 * 7) = 210
.
.
.
Last rotation: currVal = 285 + 55 – (10 * 1) = 330
Previous currVal was 285, now it becomes 330.
It’s the maximum value we can find hence return 330.
Follow the steps mentioned below to implement the above approach:
- Compute the sum of all array elements. Let this sum be ‘arrSum‘.
- Compute R0 for the given array. Let this value be currVal.
- Loop from j = 1 to N-1 to calculate the value for each rotation:
- Update the currVal using the formula mentioned above.
- Update the maximum sum accordingly in each step.
- Return the maximum value as the required answer.
Below is the implementation of the above idea.
C++
#include <iostream>
using namespace std;
int maxSum( int arr[], int n)
{
int arrSum = 0;
int currVal = 0;
for ( int i = 0; i < n; i++) {
arrSum = arrSum + arr[i];
currVal = currVal + (i * arr[i]);
}
int maxVal = currVal;
for ( int j = 1; j < n; j++) {
currVal = currVal + arrSum - n * arr[n - j];
if (currVal > maxVal)
maxVal = currVal;
}
return maxVal;
}
int main( void )
{
int arr[] = { 10, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int n = sizeof (arr) / sizeof (arr[0]);
cout << "\nMax sum is " << maxSum(arr, n);
return 0;
}
|
Java
import java.util.Arrays;
class Test {
static int arr[]
= new int [] { 10 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 };
static int maxSum()
{
int arrSum = 0 ;
int currVal = 0 ;
for ( int i = 0 ; i < arr.length; i++) {
arrSum = arrSum + arr[i];
currVal = currVal + (i * arr[i]);
}
int maxVal = currVal;
for ( int j = 1 ; j < arr.length; j++) {
currVal = currVal + arrSum
- arr.length * arr[arr.length - j];
if (currVal > maxVal)
maxVal = currVal;
}
return maxVal;
}
public static void main(String[] args)
{
System.out.println( "Max sum is " + maxSum());
}
}
|
Python
def maxSum(arr):
arrSum = 0
currVal = 0
n = len (arr)
for i in range ( 0 , n):
arrSum = arrSum + arr[i]
currVal = currVal + (i * arr[i])
maxVal = currVal
for j in range ( 1 , n):
currVal = currVal + arrSum - n * arr[n - j]
if currVal > maxVal:
maxVal = currVal
return maxVal
if __name__ = = '__main__' :
arr = [ 10 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ]
print "Max sum is: " , maxSum(arr)
|
C#
using System;
class Test {
static int [] arr
= new int [] { 10, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
static int maxSum()
{
int arrSum = 0;
int currVal = 0;
for ( int i = 0; i < arr.Length; i++) {
arrSum = arrSum + arr[i];
currVal = currVal + (i * arr[i]);
}
int maxVal = currVal;
for ( int j = 1; j < arr.Length; j++) {
currVal = currVal + arrSum
- arr.Length * arr[arr.Length - j];
if (currVal > maxVal)
maxVal = currVal;
}
return maxVal;
}
public static void Main()
{
Console.WriteLine( "Max sum is " + maxSum());
}
}
|
Javascript
<script>
function maxSum(arr, n)
{
let arrSum = 0;
let currVal = 0;
for (let i=0; i<n; i++)
{
arrSum = arrSum + arr[i];
currVal = currVal+(i*arr[i]);
}
let maxVal = currVal;
for (let j=1; j<n; j++)
{
currVal = currVal + arrSum-n*arr[n-j];
if (currVal > maxVal)
maxVal = currVal;
}
return maxVal;
}
let arr = [10, 1, 2, 3, 4, 5, 6, 7, 8, 9];
let n = arr.length;
document.write( "Max sum is " + maxSum(arr, n));
</script>
|
PHP
<?php
function maxSum( $arr , $n )
{
$arrSum = 0;
$currVal = 0;
for ( $i = 0; $i < $n ; $i ++)
{
$arrSum = $arrSum + $arr [ $i ];
$currVal = $currVal +
( $i * $arr [ $i ]);
}
$maxVal = $currVal ;
for ( $j = 1; $j < $n ; $j ++)
{
$currVal = $currVal + $arrSum -
$n * $arr [ $n - $j ];
if ( $currVal > $maxVal )
$maxVal = $currVal ;
}
return $maxVal ;
}
$arr = array (10, 1, 2, 3, 4,
5, 6, 7, 8, 9);
$n = sizeof( $arr );
echo "Max sum is " ,
maxSum( $arr , $n );
?>
|
Time Complexity: O(N)
Auxiliary Space: O(1)
Last Updated :
28 Dec, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...