📜  通过重复给定数组k次形成的数组中的最大子数组总和

📅  最后修改于: 2021-04-29 12:40:23             🧑  作者: Mango

给定一个整数kn个元素的整数数组arr [] ,任务是在修改后的数组中找到最大的子数组总和(通过重复给定数组k次来形成)。例如,如果arr [] = {1,2}且k = 3,则修改后的数组将为{1,2,1,2,1,2,2}。

例子:

一个简单的解决方案是创建一个大小为n * k的数组,然后运行Kadane算法查找最大子数组和。时间复杂度为O(n * k) ,辅助空间为O(n * k)

更好的解决方案是计算数组arr []的总和并将其存储在sum中

  • 如果sum <0,则不管K,通过两次串联该数组来计算一个数组的最大子数组和。例如,取arr [] = {1,-4,1}且k =5。该数组的总和小于0。因此,将两个数组并置后可以找到该数组的最大子数组总和。仅与K的值无关,即b [] = {1,-4,1,1,-4,1}和最大子数组总和= 1 + 1 = 2

  • 如果sum> 0,则最大子数组将包括上一步中计算的最大和(该数组被串联两次)+数组的其余重复(k – 2)也可以包括,因为它们的和大于0将贡献最大的总和。

下面是上述方法的实现:

C++
// C++ implementation of the approach
#include
using namespace std;
  
    // Function to concatenate array
    void arrayConcatenate(int *arr, int *b,
                                int k,int len)
    {
        // Array b will be formed by concatenation
        // array a exactly k times
        int j = 0;
        while (k > 0) 
        {
  
            for (int i = 0; i < len; i++)
            {
                b[j++] = arr[i];
            }
            k--;
        }
    }
  
    // Function to return the maximum 
    // subarray sum of arr[]
    long maxSubArrSum(int *a,int len)
    {
        int size = len;
        int max_so_far = INT_MIN;
        long max_ending_here = 0;
  
        for (int i = 0; i < size; i++)
        {
            max_ending_here = max_ending_here + a[i];
            if (max_so_far < max_ending_here)
                max_so_far = max_ending_here;
            if (max_ending_here < 0)
                max_ending_here = 0;
        }
        return max_so_far;
    }
  
    // Function to return the maximum sub-array 
    // sum of the modified array
    long maxSubKSum(int *arr, int k,int len)
    {
        int arrSum = 0;
        long maxSubArrSum1 = 0;
  
        int b[(2 * len)]={0};
  
        // Concatenating the array 2 times
        arrayConcatenate(arr, b, 2,len);
  
        // Finding the sum of the array
        for (int i = 0; i < len; i++)
            arrSum += arr[i];
  
        // If sum is less than zero
        if (arrSum < 0)
            maxSubArrSum1 = maxSubArrSum(b,2*len);
  
        // If sum is greater than zero
        else
            maxSubArrSum1 = maxSubArrSum(b,2*len) +
                        (k - 2) * arrSum;
  
        return maxSubArrSum1;
    }
  
    // Driver code
    int main()
    {
        int arr[] = { 1, -2, 1 };
        int arrlen=sizeof(arr)/sizeof(arr[0]);
        int k = 5;
        cout << maxSubKSum(arr, k,arrlen) << endl;
        return 0;
    }
      
// This code is contributed by mits


Java
// Java implementation of the approach
public class GFG {
  
    // Function to concatenate array
    static void arrayConcatenate(int arr[], int b[], 
                                             int k)
    {
        // Array b will be formed by concatenation
        // array a exactly k times
        int j = 0;
        while (k > 0) {
  
            for (int i = 0; i < arr.length; i++) {
                b[j++] = arr[i];
            }
            k--;
        }
    }
  
    // Function to return the maximum 
    // subarray sum of arr[]
    static int maxSubArrSum(int a[])
    {
        int size = a.length;
        int max_so_far = Integer.MIN_VALUE,
            max_ending_here = 0;
  
        for (int i = 0; i < size; i++) {
            max_ending_here = max_ending_here + a[i];
            if (max_so_far < max_ending_here)
                max_so_far = max_ending_here;
            if (max_ending_here < 0)
                max_ending_here = 0;
        }
        return max_so_far;
    }
  
    // Function to return the maximum sub-array 
    // sum of the modified array
    static long maxSubKSum(int arr[], int k)
    {
        int arrSum = 0;
        long maxSubArrSum = 0;
  
        int b[] = new int[(2 * arr.length)];
  
        // Concatenating the array 2 times
        arrayConcatenate(arr, b, 2);
  
        // Finding the sum of the array
        for (int i = 0; i < arr.length; i++)
            arrSum += arr[i];
  
        // If sum is less than zero
        if (arrSum < 0)
            maxSubArrSum = maxSubArrSum(b);
  
        // If sum is greater than zero
        else
            maxSubArrSum = maxSubArrSum(b) +
                          (k - 2) * arrSum;
  
        return maxSubArrSum;
    }
  
    // Driver code
    public static void main(String[] args)
    {
        int arr[] = { 1, -2, 1 };
        int k = 5;
        System.out.println(maxSubKSum(arr, k));
    }
}
Below is the implementation of the above approach:


Python
# Python approach to this problem
  
# A python module where element 
# are added to list k times
def MaxsumArrKtimes(c, ktimes):
      
    # Store element in list d k times
    d = c * ktimes
      
    # two variable which can keep 
    # track of maximum sum seen
    # so far and maximum sum ended.
    maxsofar = -99999
    maxending = 0
      
    for i in d:
        maxending = maxending + i
        if maxsofar < maxending:
            maxsofar = maxending
        if maxending < 0:
            maxending = 0
    return maxsofar
      
# Get the Maximum sum of element
print(MaxsumArrKtimes([1, -2, 1], 5))
      
# This code is contributed by AnupGaurav.


C#
// C# implementation of the approach 
using System;
  
class GFG 
{ 
  
// Function to concatenate array 
static void arrayConcatenate(int []arr, 
                             int []b, int k) 
{ 
    // Array b will be formed by concatenation 
    // array a exactly k times 
    int j = 0; 
    while (k > 0)
    { 
        for (int i = 0; i < arr.Length; i++) 
        { 
            b[j++] = arr[i]; 
        } 
        k--; 
    } 
} 
  
// Function to return the maximum 
// subarray sum of arr[] 
static int maxSubArrSum(int []a) 
{ 
    int size = a.Length; 
    int max_so_far = int.MinValue, 
        max_ending_here = 0; 
  
    for (int i = 0; i < size; i++) 
    { 
        max_ending_here = max_ending_here + a[i]; 
        if (max_so_far < max_ending_here) 
            max_so_far = max_ending_here; 
        if (max_ending_here < 0) 
            max_ending_here = 0; 
    } 
    return max_so_far; 
} 
  
// Function to return the maximum sub-array 
// sum of the modified array 
static long maxSubKSum(int []arr, int k) 
{ 
    int arrSum = 0; 
    long maxSubArrsum = 0; 
  
    int []b = new int[(2 * arr.Length)]; 
  
    // Concatenating the array 2 times 
    arrayConcatenate(arr, b, 2); 
  
    // Finding the sum of the array 
    for (int i = 0; i < arr.Length; i++) 
        arrSum += arr[i]; 
  
    // If sum is less than zero 
    if (arrSum < 0) 
        maxSubArrsum = maxSubArrSum(b); 
  
    // If sum is greater than zero 
    else
        maxSubArrsum = maxSubArrSum(b) + 
                       (k - 2) * arrSum; 
  
    return maxSubArrsum; 
} 
  
// Driver code 
public static void Main() 
{ 
    int []arr = { 1, -2, 1 }; 
    int k = 5; 
    Console.WriteLine(maxSubKSum(arr, k)); 
} 
} 
  
// This code is contributed by Ryuga


PHP
 0) 
    {
  
        for ($i = 0; $i < sizeof($arr); $i++) 
        {
            $b[$j++] = $arr[$i];
        }
        $k--;
    }
}
  
// Function to return the maximum 
// subarray sum of arr[]
function maxSubArrSum(&$a)
{
    $size = sizeof($a);
    $max_so_far = 0;
    $max_ending_here = 0;
  
    for ($i = 0; $i < $size; $i++) 
    {
        $max_ending_here = $max_ending_here + $a[$i];
        if ($max_so_far < $max_ending_here)
            $max_so_far = $max_ending_here;
        if ($max_ending_here < 0)
            $max_ending_here = 0;
    }
    return $max_so_far;
}
  
// Function to return the maximum sub-array 
// sum of the modified array
function maxSubKSum(&$arr,$k)
{
    $arrSum = 0;
    $maxSubArrSum = 0;
  
    $b = array_fill(0,(2 * sizeof($arr)),NULL);
  
    // Concatenating the array 2 times
    arrayConcatenate($arr, $b, 2);
  
    // Finding the sum of the array
    for ($i = 0; $i < sizeof($arr); $i++)
        $arrSum += $arr[$i];
  
    // If sum is less than zero
    if ($arrSum < 0)
        $maxSubArrSum = maxSubArrSum($b);
  
    // If sum is greater than zero
    else
        $maxSubArrSum = maxSubArrSum($b) +
                    ($k - 2) * $arrSum;
  
    return $maxSubArrSum;
}
  
    // Driver code
    $arr = array(1, -2, 1 );
    $k = 5;
    echo maxSubKSum($arr, $k);
      
// This code is contributed by Ita_c.    
?>


输出:
2