📜  至少有k个数的最大和子数组

📅  最后修改于: 2021-05-04 14:14:52             🧑  作者: Mango

给定一个数组,找到总和最大的子数组(至少包含k个数字)。

例子:

Input : arr[] = {-4, -2, 1, -3} 
            k = 2
Output : -1
The sub array is {-2, 1}

Input : arr[] = {1, 1, 1, 1, 1, 1} 
            k = 2
Output : 6 
The sub array is {1, 1, 1, 1, 1, 1}

询问:Facebook

此问题是最大和子数组问题的扩展。

1)我们首先计算最大和,直到每个索引并将其存储在数组maxSum []中。
2)填充数组后,我们使用大小为k的滑动窗口概念。跟踪当前k个元素的总和。要计算当前窗口的总和,请删除上一个窗口的第一个元素,然后添加当前元素。得到当前窗口的总和后,我们添加前一个窗口的maxSum,如果它大于当前的max,则不进行更新。

下面是上述方法的实现:

C++
// C++ program to find largest subarray sum with
// at-least k elements in it.
#include
using namespace std;
  
// Returns maximum sum of a subarray with at-least
// k elements.
int maxSumWithK(int a[], int n, int k)
{
    // maxSum[i] is going to store maximum sum
    // till index i such that a[i] is part of the
    // sum.
    int maxSum[n];
    maxSum[0] = a[0];
  
    // We use Kadane's algorithm to fill maxSum[]
    // Below code is taken from method 3 of
    // https://www.geeksforgeeks.org/largest-sum-contiguous-subarray/
    int curr_max = a[0];
    for (int i = 1; i < n; i++)
    {
        curr_max = max(a[i], curr_max+a[i]);
        maxSum[i] = curr_max;
    }
  
    // Sum of first k elements
    int sum = 0;
    for (int i = 0; i < k; i++)
        sum += a[i];
  
    // Use the concept of sliding window
    int result = sum;
    for (int i = k; i < n; i++)
    {
        // Compute sum of k elements ending
        // with a[i].
        sum = sum + a[i] - a[i-k];
  
        // Update result if required
        result = max(result, sum);
  
        // Include maximum sum till [i-k] also
        // if it increases overall max.
        result = max(result, sum + maxSum[i-k]);
    }
    return result;
}
  
// Driver code
int main()
{
    int a[] = {1, 2, 3, -10, -3};
    int k = 4;
    int n = sizeof(a)/sizeof(a[0]);
    cout << maxSumWithK(a, n, k);
    return 0;
}


Java
// Java program to find largest subarray sum with
// at-least k elements in it.
class Test
{
    // Returns maximum sum of a subarray with at-least
    // k elements.
    static int maxSumWithK(int a[], int n, int k)
    {
        // maxSum[i] is going to store maximum sum
        // till index i such that a[i] is part of the
        // sum.
        int maxSum[] = new int [n];
        maxSum[0] = a[0];
  
        // We use Kadane's algorithm to fill maxSum[]
        // Below code is taken from method 3 of
        // https://www.geeksforgeeks.org/largest-sum-contiguous-subarray/
        int curr_max = a[0];
        for (int i = 1; i < n; i++)
        {
            curr_max = Math.max(a[i], curr_max+a[i]);
            maxSum[i] = curr_max;
        }
  
        // Sum of first k elements
        int sum = 0;
        for (int i = 0; i < k; i++)
            sum += a[i];
  
        // Use the concept of sliding window
        int result = sum;
        for (int i = k; i < n; i++)
        {
            // Compute sum of k elements ending
            // with a[i].
            sum = sum + a[i] - a[i-k];
  
            // Update result if required
            result = Math.max(result, sum);
  
            // Include maximum sum till [i-k] also
            // if it increases overall max.
            result = Math.max(result, sum + maxSum[i-k]);
        }
        return result;
    }
  
    // Driver method
    public static void main(String[] args)
    {
        int arr[] = {1, 2, 3, -10, -3};
        int k = 4;
        System.out.println(maxSumWithK(arr, arr.length, k));;
    }
}


Python3
# Python3 program to find largest subarray 
# sum with at-least k elements in it.
  
# Returns maximum sum of a subarray
#  with at-least k elements.
def maxSumWithK(a, n, k):
   
    # maxSum[i] is going to store 
    # maximum sum till index i such
    # that a[i] is part of the sum.
    maxSum = [0 for i in range(n)]
    maxSum[0] = a[0]
  
    # We use Kadane's algorithm to fill maxSum[]
    # Below code is taken from method3 of
    # https://www.geeksforgeeks.org/largest-sum-contiguous-subarray/
    curr_max = a[0]
    for i in range(1, n):
      
        curr_max = max(a[i], curr_max + a[i])
        maxSum[i] = curr_max
  
    # Sum of first k elements
    sum = 0
    for i in range(k):
        sum += a[i]
  
    # Use the concept of sliding window
    result = sum
    for i in range(k, n):
      
        # Compute sum of k elements 
        # ending with a[i].
        sum = sum + a[i] - a[i-k]
  
        # Update result if required
        result = max(result, sum)
  
        # Include maximum sum till [i-k] also
        # if it increases overall max.
        result = max(result, sum + maxSum[i-k])
      
    return result
  
# Driver code
a = [1, 2, 3, -10, -3]
k = 4
n = len(a)
print(maxSumWithK(a, n, k))
  
# This code is contributed by Anant Agarwal.


C#
// C# program to find largest subarray sum with
// at-least k elements in it.
  
using System;
class Test
{
    // Returns maximum sum of a subarray with at-least
    // k elements.
    static int maxSumWithK(int[] a, int n, int k)
    {
        // maxSum[i] is going to store maximum sum
        // till index i such that a[i] is part of the
        // sum.
        int[] maxSum = new int [n];
        maxSum[0] = a[0];
   
        // We use Kadane's algorithm to fill maxSum[]
        // Below code is taken from method 3 of
        // https://www.geeksforgeeks.org/largest-sum-contiguous-subarray/
        int curr_max = a[0];
        for (int i = 1; i < n; i++)
        {
            curr_max = Math.Max(a[i], curr_max+a[i]);
            maxSum[i] = curr_max;
        }
   
        // Sum of first k elements
        int sum = 0;
        for (int i = 0; i < k; i++)
            sum += a[i];
   
        // Use the concept of sliding window
        int result = sum;
        for (int i = k; i < n; i++)
        {
            // Compute sum of k elements ending
            // with a[i].
            sum = sum + a[i] - a[i-k];
   
            // Update result if required
            result = Math.Max(result, sum);
   
            // Include maximum sum till [i-k] also
            // if it increases overall max.
            result = Math.Max(result, sum + maxSum[i-k]);
        }
        return result;
    }
   
    // Driver method
    public static void Main()
    {
        int[] arr = {1, 2, 3, -10, -3};
        int k = 4;
        Console.Write(maxSumWithK(arr, arr.Length, k));;
    }
}


PHP


输出:

-4

时间复杂度: O(n)