Maximum sum subarray having sum less than or equal to given sum
You are given an array of non-negative integers and a target sum. Your task is to find a contiguous subarray whose sum is the maximum possible, while ensuring that it does not exceed the given target sum.
Note: The given array contains only non-negative integers.
Examples:
Input: arr[] = [1, 2, 3, 4, 5], sum = 11
Output: 10
Explanation: Subarray having maximum sum is [1, 2, 3, 4]
Input: arr[] = [2, 4, 6, 8, 10], sum = 7
Output: 6
Explanation: Subarray having maximum sum is [2, 4]or [6]
Table of Content
[Naive Approach] - Generate all Subarrays - O(n^2) Time and O(1) Space
We can solve this problem by generating all substrings, comparing their sums with the given sum, and updating the answer accordingly.
#include <bits/stdc++.h>
using namespace std;
int findMaxSubarraySum(vector<int> &arr, int sum)
{
int result = 0;
int n = arr.size();
for (int i = 0; i < n; i++) {
int currSum = 0;
for (int j = i; j < n; j++) {
currSum += arr[j];
if (currSum < sum) {
result = max(result, currSum);
}
}
}
return result;
}
// Driver program to test above function
int main()
{
vector<int> arr= { 6, 8, 9 };
int sum = 20;
cout << findMaxSubarraySum(arr, sum);
return 0;
}
using namespace std;
int findMaxSubarraySum(vector<int> &arr, int sum)
{
int result = 0;
int n = arr.size();
for (int i = 0; i < n; i++) {
int currSum = 0;
for (int j = i; j < n; j++) {
currSum += arr[j];
if (currSum < sum) {
result = max(result, currSum);
}
}
}
return result;
}
// Driver program to test above function
int main()
{
vector<int> arr= { 6, 8, 9 };
int sum = 20;
cout << findMaxSubarraySum(arr, sum);
return 0;
}
import java.io.*;
import java.util.*;
public class GfG {
static int findMaxSubarraySum(int[] arr, int sum)
{
int result = 0;
int n = arr.length;
for (int i = 0; i < n; i++) {
int currSum = 0;
for (int j = i; j < n; j++) {
currSum += arr[j];
if (currSum < sum) {
result = Math.max(result, currSum);
}
}
}
return result;
}
public static void main(String[] args)
{
int[] arr = { 6, 8, 9 };
int sum = 20;
System.out.println(findMaxSubarraySum(arr, sum));
}
}
def findMaxSubarraySum(arr, sum):
result = 0
n = len(arr)
for i in range(n):
currSum = 0
for j in range(i, n):
currSum += arr[j]
if currSum < sum:
result = max(result, currSum)
return result
if __name__ == '__main__':
arr = [6, 8, 9]
sum = 20
print(findMaxSubarraySum(arr, sum))
using System;
class GfG {
static int findMaxSubarraySum(int[] arr, int sum)
{
int result = 0;
int n = arr.Length;
for (int i = 0; i < n; i++) {
int currSum = 0;
for (int j = i; j < n; j++) {
currSum += arr[j];
if (currSum < sum) {
result = Math.Max(result, currSum);
}
}
}
return result;
}
public static void Main()
{
int[] arr = { 6, 8, 9 };
int sum = 20;
Console.WriteLine(findMaxSubarraySum(arr, sum));
}
}
function findMaxSubarraySum(arr, sum)
{
let result = 0;
let n = arr.length;
for (let i = 0; i < n; i++) {
let currSum = 0;
for (let j = i; j < n; j++) {
currSum += arr[j];
if (currSum < sum) {
result = Math.max(result, currSum);
}
}
}
return result;
}
const arr = [ 6, 8, 9 ];
const sum = 20;
console.log(findMaxSubarraySum(arr, sum));
Output
17
[Expected Approach] - Using Sliding Window - O(n) Time and O(n) Space
The maximum sum subarray can be found using a sliding window approach. Start by adding elements to
curr_sum
while it's less than the target sum. Ifcurr_sum
exceeds the sum, remove elements from the start until it fits within the limit. (Note: This method works only for non-negative elements.)
#include <bits/stdc++.h>
using namespace std;
int findMaxSubarraySum(vector<int> &arr, int sum)
{
int n = arr.size();
int curr_sum = arr[0], max_sum = 0, start = 0;
for (int i = 1; i < n; i++) {
if (curr_sum <= sum)
max_sum = max(max_sum, curr_sum);
while (start < i && curr_sum + arr[i] > sum) {
curr_sum -= arr[start];
start++;
}
if (curr_sum < 0)
{
curr_sum = 0;
}
curr_sum += arr[i];
}
if (curr_sum <= sum)
max_sum = max(max_sum, curr_sum);
return max_sum;
}
int main()
{
vector<int> arr = {6, 8, 9};
int sum = 20;
cout << findMaxSubarraySum(arr, sum);
return 0;
}
using namespace std;
int findMaxSubarraySum(vector<int> &arr, int sum)
{
int n = arr.size();
int curr_sum = arr[0], max_sum = 0, start = 0;
for (int i = 1; i < n; i++) {
if (curr_sum <= sum)
max_sum = max(max_sum, curr_sum);
while (start < i && curr_sum + arr[i] > sum) {
curr_sum -= arr[start];
start++;
}
if (curr_sum < 0)
{
curr_sum = 0;
}
curr_sum += arr[i];
}
if (curr_sum <= sum)
max_sum = max(max_sum, curr_sum);
return max_sum;
}
int main()
{
vector<int> arr = {6, 8, 9};
int sum = 20;
cout << findMaxSubarraySum(arr, sum);
return 0;
}
class GfG{
static int findMaxSubarraySum(int arr[], int sum)
{
int n = arr.length;
int curr_sum = arr[0], max_sum = 0, start = 0;
// To find max_sum less than sum
for (int i = 1; i < n; i++) {
if (curr_sum <= sum)
max_sum = Math.max(max_sum, curr_sum);
while (curr_sum + arr[i] > sum && start < i) {
curr_sum -= arr[start];
start++;
}
// Add elements to curr_sum
curr_sum += arr[i];
}
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[] = {6, 8, 9};
int sum = 20;
System.out.println(findMaxSubarraySum(arr, sum));
}
}
def findMaxSubarraySum(arr, n, sum):
curr_sum = arr[0]
max_sum = 0
start = 0;
for i in range(1, n):
if (curr_sum <= sum):
max_sum = max(max_sum, curr_sum)
while (curr_sum + arr[i] > sum and start < i):
curr_sum -= arr[start]
start += 1
curr_sum += arr[i]
if (curr_sum <= sum):
max_sum = max(max_sum, curr_sum)
return max_sum
if __name__ == '__main__':
arr = [6, 8, 9]
n = len(arr)
sum = 20
print(findMaxSubarraySum(arr, n, sum))
using System;
class GfG {
static int findMaxSubarraySum(int[] arr, int sum)
{
int n = arr.Length;
int curr_sum = arr[0], max_sum = 0, start = 0;
for (int i = 1; i < n; i++) {
if (curr_sum <= sum)
max_sum = Math.Max(max_sum, curr_sum);
while (curr_sum + arr[i] > sum && start < i) {
curr_sum -= arr[start];
start++;
}
curr_sum += arr[i];
}
if (curr_sum <= sum)
max_sum = Math.Max(max_sum, curr_sum);
return max_sum;
}
// Driver Code
public static void Main()
{
int[] arr = { 6, 8, 9 };
int sum = 20;
Console.Write(findMaxSubarraySum(arr, sum));
}
}
function findMaxSubarraySum(arr, sum)
{
let n = arr.length;
let curr_sum = arr[0], max_sum = 0,
start = 0;
for(let i = 1; i < n; i++)
{
if (curr_sum <= sum)
max_sum = Math.max(max_sum, curr_sum);
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
let arr = [ 6, 8, 9 ];
let sum = 20;
console.log(findMaxSubarraySum(arr, sum));
Output
17
Note: For an array containing positive, negative, and zero elements, we can use the prefix sum along with sets to efficiently find the solution. The worst-case time complexity for this approach is O(n log n).
For a detailed explanation, refer to the article Maximum Subarray Sum Less Than or Equal to K Using Set.