📌  相关文章
📜  查找 Sum(i*arr[i]) 的最大值,仅允许在给定数组上进行旋转

📅  最后修改于: 2022-05-13 01:57:48.765000             🧑  作者: Mango

查找 Sum(i*arr[i]) 的最大值,仅允许在给定数组上进行旋转

给定一个数组,只允许对数组进行旋转操作。我们可以根据需要多次旋转数组。返回 i*arr[i] 的最大可能总和。

例子 :

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

我们强烈建议您最小化您的浏览器并首先自己尝试。
一个简单的解决方案是逐个找到所有旋转,检查每个旋转的总和并返回最大总和。该解决方案的时间复杂度为 O(n 2 )。

我们可以使用Efficient Solution在 O(n) 时间内解决这个问题。
令 R j为 i*arr[i] 的值,旋转 j 次。这个想法是从前一个旋转计算下一个旋转值,即从 R j-1计算 R j 。我们可以将结果的初始值计算为 R 0 ,然后继续计算下一个旋转值。

如何从 R j-1有效地计算 R j
这可以在 O(1) 时间内完成。以下是详细信息。

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 

下面是完整的算法:

1) Compute sum of all array elements. Let this sum be 'arrSum'.

2) Compute R0 by doing i*arr[i] for given array. 
   Let this value be currVal.

3) Initialize result: maxVal = currVal // maxVal is result.

// This loop computes Rj from  Rj-1 
4) Do following for j = 1 to n-1
......a) currVal = currVal + arrSum-n*arr[n-j];
......b) If (currVal > maxVal)
            maxVal = currVal   

5) Return maxVal

以下是上述想法的实现:

C++
// C++ program to find max value of i*arr[i]
#include 
using namespace std;
 
// Returns max possible value of i*arr[i]
int maxSum(int arr[], int n)
{
    // Find array sum and i*arr[i] with no rotation
    int arrSum = 0;  // Stores sum of arr[i]
    int currVal = 0;  // Stores sum of i*arr[i]
    for (int i=0; i maxVal)
            maxVal = currVal;
    }
 
    // Return result
    return maxVal;
}
 
// Driver program
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
// Java program to find max value of i*arr[i]
 
import java.util.Arrays;
 
class Test
{
    static int arr[] = new int[]{10, 1, 2, 3, 4, 5, 6, 7, 8, 9};
     
    // Returns max possible value of i*arr[i]
    static int maxSum()
    {
        // Find array sum and i*arr[i] with no rotation
        int arrSum = 0;  // Stores sum of arr[i]
        int currVal = 0;  // Stores sum of i*arr[i]
        for (int i=0; i maxVal)
                maxVal = currVal;
        }
      
        // Return result
        return maxVal;
    }
     
    // Driver method to test the above function
    public static void main(String[] args)
    {
        System.out.println("Max sum is " + maxSum());
    }
}


Python
'''Python program to find maximum value of Sum(i*arr[i])'''
 
# returns max possible value of Sum(i*arr[i])
def maxSum(arr):
 
    # stores sum of arr[i]
    arrSum = 0   
 
    # stores sum of i*arr[i]
    currVal = 0
     
    n = len(arr)
 
    for i in range(0, n):
        arrSum = arrSum + arr[i]
        currVal = currVal + (i*arr[i])
 
    # initialize result
    maxVal = currVal
 
    # try all rotations one by one and find the maximum
    # rotation sum
    for j in range(1, n):
        currVal = currVal + arrSum-n*arr[n-j]
        if currVal > maxVal:
            maxVal = currVal
 
    # return result
    return maxVal
 
# test maxsum(arr) function
arr = [10, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print "Max sum is: ", maxSum(arr)


C#
// C# program to find max value of i*arr[i]
using System;
 
class Test
{
    static int []arr = new int[]{10, 1, 2, 3, 4,
                                  5, 6, 7, 8, 9};
     
    // Returns max possible value of i*arr[i]
    static int maxSum()
    {
        // Find array sum and i*arr[i]
        // with no rotation
        int arrSum = 0; // Stores sum of arr[i]
        int currVal = 0; // Stores sum of i*arr[i]
         
        for (int i = 0; i < arr.Length; i++)
        {
            arrSum = arrSum + arr[i];
            currVal = currVal + (i * arr[i]);
        }
     
        // Initialize result as 0 rotation sum
        int maxVal = currVal;
     
        // Try all rotations one by one and find
        // the maximum rotation sum.
        for (int j = 1; j < arr.Length; j++)
        {
            currVal = currVal + arrSum - arr.Length *
                                arr[arr.Length - j];
            if (currVal > maxVal)
                maxVal = currVal;
        }
     
        // Return result
        return maxVal;
    }
     
    // Driver Code
    public static void Main()
    {
        Console.WriteLine("Max sum is " + maxSum());
    }
}
 
// This article is contributed by vt_m.


PHP
 $maxVal)
            $maxVal = $currVal;
    }
 
    // Return result
    return $maxVal;
}
 
// Driver Code
$arr = array (10, 1, 2, 3, 4,
              5, 6, 7, 8, 9);
$n = sizeof($arr);
echo "Max sum is " ,
     maxSum($arr, $n);
 
// This code is contributed by m_kit
?>


Javascript


输出 :

Max sum is 330

时间复杂度: O(n)
辅助空间: O(1)