给定一个长度为N的数组arr[]和一个整数K ,任务是找到总和小于K的最大和子数组。
注意:如果 K 小于最小元素,则返回 INT_MIN。
例子:
Input: arr[] = {-1, 2, 2}, K = 4
Output: 3
Explanation:
The subarray with maximum sum which is less than 4 is {-1, 2, 2}.
The subarray {2, 2} has maximum sum = 4, but it is not less than 4.
Input: arr[] = {5, -2, 6, 3, -5}, K =15
Output: 12
Explanation:
The subarray with maximum sum which is less than 15 is {5, -2, 6, 3}.
有效方法:子数组 [i, j] 的总和由数组的累积和直到 j – 累积和直到 i给出。现在问题简化为找到两个索引 i 和 j,使得 i < j 和cum[j] – cum[i]与K一样接近但小于它。
为了解决这个问题,从左到右迭代数组。将您迄今为止遇到的 i 个值的累积总和放入一个集合中。当您处理 cum[j] 时,您需要从集合中检索的是集合中大于cum[j] – K的最小数字。这可以在 O(logN) 中使用集合上的 upper_bound 来完成。
下面是上述方法的实现:
C++
// C++ program to find maximum sum
// subarray less than K
#include
using namespace std;
// Function to maximum required sum < K
int maxSubarraySum(int arr[], int N, int K)
{
// Hash to lookup for value (cum_sum - K)
set cum_set;
cum_set.insert(0);
int max_sum = INT_MIN, cSum = 0;
for (int i = 0; i < N; i++) {
// getting cummulative sum from [0 to i]
cSum += arr[i];
// lookup for upperbound
// of (cSum-K) in hash
set::iterator sit
= cum_set.lower_bound(cSum - K);
// check if upper_bound
// of (cSum-K) exists
// then update max sum
if (sit != cum_set.end())
max_sum = max(max_sum, cSum - *sit);
// insert cummulative value in hash
cum_set.insert(cSum);
}
// return maximum sum
// lesser than K
return max_sum;
}
// Driver code
int main()
{
// initialise the array
int arr[] = { 5, -2, 6, 3, -5 };
// initialise the vaue of K
int K = 15;
// size of array
int N = sizeof(arr) / sizeof(arr[0]);
cout << maxSubarraySum(arr, N, K);
return 0;
}
Java
// Java program to find maximum sum
// subarray less than K
import java.util.*;
import java.io.*;
class GFG{
// Function to maximum required sum < K
static int maxSubarraySum(int arr[], int N,
int K)
{
// Hash to lookup for value (cum_sum - K)
Set cum_set = new HashSet<>();
cum_set.add(0);
int max_sum =Integer.MIN_VALUE, cSum = 0;
for(int i = 0; i < N; i++)
{
// Getting cummulative sum from [0 to i]
cSum += arr[i];
// Lookup for upperbound
// of (cSum-K) in hash
ArrayList al = new ArrayList<>();
Iterator it = cum_set.iterator();
int end = 0;
while (it.hasNext())
{
end = it.next();
al.add(end);
}
Collections.sort(al);
int sit = lower_bound(al, cSum - K);
// Check if upper_bound
// of (cSum-K) exists
// then update max sum
if (sit != end)
max_sum = Math.max(max_sum,
cSum - sit);
// Insert cummulative value in hash
cum_set.add(cSum);
}
// Return maximum sum
// lesser than K
return max_sum;
}
static int lower_bound(ArrayList al,
int x)
{
// x is the target value or key
int l = -1, r = al.size();
while (l + 1 < r)
{
int m = (l + r) >>> 1;
if (al.get(m) >= x)
r = m;
else
l = m;
}
return r;
}
// Driver code
public static void main(String args[])
{
// Initialise the array
int arr[] = { 5, -2, 6, 3, -5 };
// Initialise the vaue of K
int K = 15;
// Size of array
int N = arr.length;
System.out.println(maxSubarraySum(arr, N, K));
}
}
// This code is contributed by jyoti369
Python3
# Python3 program to find maximum sum
# subarray less than K
import sys
import bisect
# Function to maximum required sum < K
def maxSubarraySum(arr, N, K):
# Hash to lookup for value (cum_sum - K)
cum_set = set()
cum_set.add(0)
max_sum = 12
cSum = 0
for i in range(N):
# getting cummulative sum from [0 to i]
cSum += arr[i]
# check if upper_bound
# of (cSum-K) exists
# then update max sum
x = bisect.bisect_left(arr, cSum - K, lo=0, hi=len(arr))
if x:
max_sum = max(max_sum,x )
# insert cummulative value in hash
cum_set.add(cSum)
# return maximum sum
# lesser than K
return max_sum
# Driver code
if __name__ == '__main__':
# initialise the array
arr = [5, -2, 6, 3, -5]
# initialise the vaue of K
K = 15
# size of array
N = len(arr)
print(maxSubarraySum(arr, N, K))
# This code is contributed by Surendra_Gangwar
C#
// Java program to find maximum sum
// subarray less than K
using System;
using System.Collections.Generic;
class GFG {
// Function to maximum required sum < K
static int maxSubarraySum(int[] arr, int N, int K)
{
// Hash to lookup for value (cum_sum - K)
HashSet cum_set = new HashSet();
cum_set.Add(0);
int max_sum = Int32.MinValue, cSum = 0;
for (int i = 0; i < N; i++) {
// Getting cummulative sum from [0 to i]
cSum += arr[i];
// Lookup for upperbound
// of (cSum-K) in hash
List al = new List();
int end = 0;
foreach(int it in cum_set)
{
end = it;
al.Add(it);
}
al.Sort();
int sit = lower_bound(al, cSum - K);
// Check if upper_bound
// of (cSum-K) exists
// then update max sum
if (sit != end)
max_sum = Math.Max(max_sum, cSum - sit);
// Insert cummulative value in hash
cum_set.Add(cSum);
}
// Return maximum sum
// lesser than K
return max_sum;
}
static int lower_bound(List al, int x)
{
// x is the target value or key
int l = -1, r = al.Count;
while (l + 1 < r) {
int m = (l + r) >> 1;
if (al[m] >= x)
r = m;
else
l = m;
}
return r;
}
// Driver code
public static void Main(string[] args)
{
// Initialise the array
int[] arr = { 5, -2, 6, 3, -5 };
// Initialise the vaue of K
int K = 15;
// Size of array
int N = arr.Length;
Console.Write(maxSubarraySum(arr, N, K));
}
}
// This code is contributed by chitranayal.
Javascript
12
时间复杂度: O(N*Log(N))
类似文章:使用滑动窗口的总和小于或等于给定总和的最大总和子数组
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live