📜  重复连接后创建的数组中的最大子数组和 |第 2 组

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

重复连接后创建的数组中的最大子数组和 |第 2 组

给定一个数组 arr[]N个整数和一个正整数K组成,任务是在通过重复给定数组K次形成的修改数组中找到任何连续子数组的最大和。

例子:

朴素方法:解决问题的最简单方法在 Set-1 中讨论。

有效的方法:上述方法可以根据以下观察进一步优化:

  1. 如果数组的总和大于0 ,那么它将有助于答案。否则,将所有数组元素都包含在最大子数组中是不好的。
  2. 假设变量maxPrefixmaxSufix存储了两次重复数组的最大前缀和和最大后缀和。
  3. 因此,最大和子数组可以通过以下两种方式之一形成:
    1. 附加由组合前两个数组形成的数组的maxSufix的元素,然后附加剩余的N-2 个数组。
    2. 首先追加N-2个数组,然后追加组合最后两个数组形成的数组的maxPrefix的元素。
    3. 取两次重复数组的最大和子数组的所有元素。

请按照以下步骤解决问题:

  • 找到数组arr[]的总和并将其存储在一个变量中,比如sum1
  • 初始化一个变量,比如sumans0以存储当前最大和和答案。
  • 如果K = 1 ,则打印数组arr[] 的最大子数组和。
  • 否则,将数组arr[]的元素从[0, N-1]插入到数组V[]中两次。
  • 找到数组V[]的最大前缀和并将其存储在一个变量中,比如maxPrefix
  • 找到数组V[]的最大后缀和并将其存储在一个变量中,比如maxSufix
  • 使用变量i[0, 2*N-1]范围内迭代并执行以下步骤:
    • sum的值修改为max(sum + arr[i], arr[i]) ,将ans的值更新为max(ans, sum)。
  • 如果sum1 > 0,则将ans更新为{ans, sum1*(K-2)+maxPrefix, sum1*(K-2)*maxSufix} 的最大值。
  • 最后,完成以上步骤后,打印ans的值作为答案。

下面是上述方法的实现:

C++14
// C++ program for the above approach
#include 
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 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 V = new  ArrayList();
 
    // 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


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 V = new List();
 
        // 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.


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.


Javascript


输出
391

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