Leetcode 396.旋轉函式
旋轉函式
給定一個長度為 n 的整數陣列 A 。
假設 Bk 是陣列 A 順時針旋轉 k 個位置後的陣列,我們定義 A 的"旋轉函式" F 為:
F(k) = 0 * Bk[0] + 1 * Bk[1] + ... + (n-1) * Bk[n-1]。
計算F(0), F(1), ..., F(n-1)中的最大值。
注意:
可以認為 n 的值小於 105。
示例:
A = [4, 3, 2, 6]
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
所以 F(0), F(1), F(2), F(3) 中的最大值是 F(3) = 26 。
解題思想
其實就是給了一個數組A,和一個方程,方程簡單來說就是所有 第i位(從0開始)的值A[i]乘上i的積的和。現在允許你把數字迴圈位移(所有位置都可以,保證相對位置不變),找出取值最大的那一個。
其實方程的計算不難,這題是關鍵如何計算不同迴圈位移的值(肯定不能每次都直接計算)。
這裡的方式很簡單,因為都是向右迴圈位移,那麼除了當前陣列的最後一個位置,全部都多了一個,而最後一個少了n-1個(從n-1的係數變成0)。
那麼我們改變下,假設現在方程值是f,A的所有值的和是sa
那麼一次向右迴圈位移可以認為
1、首先所有值都加一個自身,也就是和加上sa
2、扣除1中多加的最後一個,以及原來就應該減掉的n個了,減掉A[n-i]*n就好
找到上面每個當中取值最大的就可以
1 public class Solution { 2 publicint maxRotateFunction(int[] A) { 3 int n = A.length; 4 //假設不旋轉下的f0的值 5 int f0 = 0; 6 // 當順序位移一位後,丟擲變成0的那個,那麼整體增加的 7 int sumOfA = 0; 8 for(int i=0;i<n;i++){ 9 f0 += A[i] * i; 10 sumOfA += A[i]; 11 } 12 int max = f0; 13 int fi = f0; //開始考慮旋轉的 14 for(int i=1;i<n;i++){ 15 //旋轉後,所有加1 16 fi += sumOfA; 17 //上一回合的 最後一個需要減去n個(原來n-1 剛剛又加了一個) 18 fi -= n * A[ n -i ]; 19 max = Math.max(max,fi); 20 } 21 return max; 22 } 23 }