总和小于或等于给定总和的最大总和子数组
给定一个非负整数数组和一个总和。我们必须找到最大和小于或等于数组中给定和的子数组的总和。
(注意:给定数组仅包含非负整数。)
例子:
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 以更清楚地了解此方法。