📌  相关文章
📜  总和小于或等于给定总和的最大总和子数组

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

总和小于或等于给定总和的最大总和子数组

给定一个非负整数数组和一个总和。我们必须找到最大和小于或等于数组中给定和的子数组的总和。

(注意:给定数组仅包含非负整数。)

例子:

Input : arr[] = { 1, 2, 3, 4, 5 }
        sum = 11
Output : 10
Subarray having maximum sum is { 1, 2, 3, 4 }

Input : arr[] = { 2, 4, 6, 8, 10 }
        sum = 7
Output : 6
Subarray having maximum sum is { 2, 4 } or { 6 }

天真的方法:我们可以通过运行两个循环来找到子数组的最大和。但是时间复杂度将是 O(N*N)。

有效方法:使用滑动窗口可以找到具有最大和的子数组。如果 curr_sum 小于 sum 包括数组元素。如果它变得大于 sum,则从 curr_sum 中的开头删除元素。 (这仅适用于非负元素的情况。)

C++
// C++ program to find subarray having
// maximum sum less than or equal to sum
#include 
using namespace std;
 
// To find subarray with maximum sum
// less than or equal to sum
int findMaxSubarraySum(int arr[], int n, int sum)
{
    // To store current sum and
    // max sum of subarrays
    int curr_sum = arr[0], max_sum = 0, start = 0;
 
    // To find max_sum less than sum
    for (int i = 1; i < n; i++) {
 
        // Update max_sum if it becomes
        // greater than curr_sum
        if (curr_sum <= sum)
            max_sum = max(max_sum, curr_sum);
 
        // If curr_sum becomes greater than
        // sum subtract starting elements of array
        while (start < i && curr_sum + arr[i] > sum) {
            curr_sum -= arr[start];
            start++;
        }
 
        // If cur_sum becomes negative then start new subarray
        if (curr_sum < 0)
        {
            curr_sum = 0;
        }
 
        // Add elements to curr_sum
        curr_sum += arr[i];
 
    }
 
    // Adding an extra check for last subarray
    if (curr_sum <= sum)
        max_sum = max(max_sum, curr_sum);
 
    return max_sum;
}
 
// Driver program to test above function
int main()
{
    int arr[] = {6, 8, 9};
    int n = sizeof(arr) / sizeof(arr[0]);
    int sum = 20;
 
    cout << findMaxSubarraySum(arr, n, sum);
 
    return 0;
}


Java
// Java program to find subarray having
// maximum sum less than or equal to sum
public class Main {
 
    // To find subarray with maximum sum
    // less than or equal to sum
    static int findMaxSubarraySum(int arr[],
                             int n, int sum)
    {
    // To store current sum and
    // max sum of subarrays
    int curr_sum = arr[0], max_sum = 0, start = 0;
 
    // To find max_sum less than sum
    for (int i = 1; i < n; i++) {
 
        // Update max_sum if it becomes
        // greater than curr_sum
        if (curr_sum <= sum)
           max_sum = Math.max(max_sum, curr_sum);
 
        // If curr_sum becomes greater than
        // sum subtract starting elements of array
        while (curr_sum + arr[i] > sum && start < i) {
            curr_sum -= arr[start];
            start++;
        }
         
        // Add elements to curr_sum
        curr_sum += arr[i];
    }
 
    // Adding an extra check for last subarray
    if (curr_sum <= sum)
        max_sum = Math.max(max_sum, curr_sum);
 
    return max_sum;
    }
 
    // Driver program to test above function
    public static void main(String[] args)
    {
        int arr[] = { 1, 2, 3, 4, 5 };
        int n = arr.length;
        int sum = 11;
 
        System.out.println(findMaxSubarraySum(arr, n, sum));
    }
}


Python3
# Python3 program to find subarray having
# maximum sum less than or equal to sum
 
# To find subarray with maximum sum
# less than or equal to sum
def findMaxSubarraySum(arr, n, sum):
     
    # To store current sum and
    # max sum of subarrays
    curr_sum = arr[0]
    max_sum = 0
    start = 0;
 
    # To find max_sum less than sum
    for i in range(1, n):
         
        # Update max_sum if it becomes
        # greater than curr_sum
        if (curr_sum <= sum):
            max_sum = max(max_sum, curr_sum)
 
        # If curr_sum becomes greater than sum
        # subtract starting elements of array
        while (curr_sum + arr[i] > sum and start < i):
            curr_sum -= arr[start]
            start += 1
         
        # Add elements to curr_sum
        curr_sum += arr[i]
 
    # Adding an extra check for last subarray
    if (curr_sum <= sum):
        max_sum = max(max_sum, curr_sum)
 
    return max_sum
 
# Driver Code
if __name__ == '__main__':
    arr = [6, 8, 9]
    n = len(arr)
    sum = 20
 
    print(findMaxSubarraySum(arr, n, sum))
 
# This code is contributed by
# Surendra_Gangwar


C#
// C# program to find subarray
// having maximum sum less
//than or equal to sum
using System;
 
public class GFG
{
 
    // To find subarray with maximum
    // sum less than or equal
    // to sum
    static int findMaxSubarraySum(int []arr,
                             int n, int sum)
    {    // To store current sum and
    // max sum of subarrays
    int curr_sum = arr[0], max_sum = 0, start = 0;
 
    // To find max_sum less than sum
    for (int i = 1; i < n; i++) {
 
        // Update max_sum if it becomes
        // greater than curr_sum
        if (curr_sum <= sum)
           max_sum = Math.Max(max_sum, curr_sum);
 
        // If curr_sum becomes greater than
        // sum subtract starting elements of array
        while (curr_sum + arr[i] > sum && start < i) {
            curr_sum -= arr[start];
            start++;
        }
         
        // Add elements to curr_sum
        curr_sum += arr[i];
    }
 
    // Adding an extra check for last subarray
    if (curr_sum <= sum)
        max_sum = Math.Max(max_sum, curr_sum);
 
    return max_sum;
    }
 
    // Driver Code
    public static void Main()
    {
        int []arr = {1, 2, 3, 4, 5};
        int n = arr.Length;
        int sum = 11;
 
        Console.Write(findMaxSubarraySum(arr, n, sum));
    }
}
 
// This code is contributed by Nitin Mittal.


PHP
 $sum &&
                             $start < $i)
        {
            $curr_sum -= $arr[$start];
            $start++;
        }
         
        // Add elements to curr_sum
        $curr_sum += $arr[$i];
    }
 
    // Adding an extra check for last subarray
    if ($curr_sum <= $sum)
        $max_sum = max($max_sum, $curr_sum);
 
    return $max_sum;
}
 
// Driver Code
$arr = array(6, 8, 9);
$n = sizeof($arr);
$sum = 20;
 
echo findMaxSubarraySum($arr, $n, $sum);
 
// This code is contributed by ita_c
?>


Javascript


输出:
17

时间复杂度: O(N*log(N))

辅助空间: O(1)

如果给定一个包含所有元素类型(正、负或零)的数组,我们可以使用前缀和和集合,最坏情况的时间复杂度为 O(n.log(n))。您可以使用 set article 参考最大子数组总和小于或等于 k 以更清楚地了解此方法。