Array Dynamic Programming Math
Description You are given an integer array nums of length n.
Assume arrk to be an array obtained by rotating nums by k positions clock-wise. We define the rotation function F on nums as follow:
F(k) = 0 * arrk [0] + 1 * arrk [1] + ... + (n - 1) * arrk [n - 1]. Return the maximum value of F(0), F(1), ..., F(n-1).
The test cases are generated so that the answer fits in a 32-bit integer.
Example 1:
Input: nums = [4,3,2,6]
Output: 26
Explanation:
F(0) = (0 * 4) + (1 * 3) + (2 * 2) + (3 * 6) = 0 + 3 + 4 + 18 = 25
F(1) = (0 * 6) + (1 * 4) + (2 * 3) + (3 * 2) = 0 + 4 + 6 + 6 = 16
F(2) = (0 * 2) + (1 * 6) + (2 * 4) + (3 * 3) = 0 + 6 + 8 + 9 = 23
F(3) = (0 * 3) + (1 * 2) + (2 * 6) + (3 * 4) = 0 + 2 + 12 + 12 = 26
So the maximum value of F(0), F(1), F(2), F(3) is F(3) = 26.
Example 2:
Input: nums = [100]
Output: 0
Constraints:
n == nums.length 1 <= n <= 105 -100 <= nums[i] <= 100 Solutions Solution 1 Thinking
\(F(k)=\sum i\cdot \textit{nums}[(i+k)\bmod n]\) ; maximize \(F\) . Recomputing each rotation is \(O(n^2)\) . Consecutive \(F\) values differ by a closed form.
\(F(k+1)=F(k)+\sum nums-n\cdot nums[n-1-k]\) . Compute \(F(0)\) , then roll \(n-1\) times and keep the max.
Python3 Java C++ Go TypeScript Rust
class Solution :
def maxRotateFunction ( self , nums : List [ int ]) -> int :
f = sum ( i * v for i , v in enumerate ( nums ))
n , s = len ( nums ), sum ( nums )
ans = f
for i in range ( 1 , n ):
f = f + s - n * nums [ n - i ]
ans = max ( ans , f )
return ans
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 class Solution {
public int maxRotateFunction ( int [] nums ) {
int f = 0 ;
int s = 0 ;
int n = nums . length ;
for ( int i = 0 ; i < n ; ++ i ) {
f += i * nums [ i ] ;
s += nums [ i ] ;
}
int ans = f ;
for ( int i = 1 ; i < n ; ++ i ) {
f = f + s - n * nums [ n - i ] ;
ans = Math . max ( ans , f );
}
return ans ;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 class Solution {
public :
int maxRotateFunction ( vector < int >& nums ) {
int f = 0 , s = 0 , n = nums . size ();
for ( int i = 0 ; i < n ; ++ i ) {
f += i * nums [ i ];
s += nums [ i ];
}
int ans = f ;
for ( int i = 1 ; i < n ; ++ i ) {
f = f + s - n * nums [ n - i ];
ans = max ( ans , f );
}
return ans ;
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13 func maxRotateFunction ( nums [] int ) int {
f , s , n := 0 , 0 , len ( nums )
for i , v := range nums {
f += i * v
s += v
}
ans := f
for i := 1 ; i < n ; i ++ {
f = f + s - n * nums [ n - i ]
ans = max ( ans , f )
}
return ans
}
function maxRotateFunction ( nums : number []) : number {
const n = nums . length ;
const sum = nums . reduce (( r , v ) => r + v );
let res = nums . reduce (( r , v , i ) => r + v * i , 0 );
let pre = res ;
for ( let i = 1 ; i < n ; i ++ ) {
pre = pre - ( sum - nums [ i - 1 ]) + nums [ i - 1 ] * ( n - 1 );
res = Math . max ( res , pre );
}
return res ;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 impl Solution {
pub fn max_rotate_function ( nums : Vec < i32 > ) -> i32 {
let n = nums . len ();
let sum : i32 = nums . iter (). sum ();
let mut pre : i32 = nums . iter (). enumerate (). map ( | ( i , & v ) | ( i as i32 ) * v ). sum ();
( 0 .. n )
. map ( | i | {
let res = pre ;
pre = pre - ( sum - nums [ i ]) + nums [ i ] * (( n - 1 ) as i32 );
res
})
. max ()
. unwrap_or ( 0 )
}
}
GitHub