find a subarray that contains the largest sum, constraint that sum is less than k

来源:互联网 发布:傻瓜音乐剪辑软件 编辑:程序博客网 时间:2024/05/21 06:30

Given an array of integers A and an integer k, find a subarray that contains the largest sum, subject to a constraint that the sum is less than k?


摘自

https://www.quora.com/Given-an-array-of-integers-A-and-an-integer-k-find-a-subarray-that-contains-the-largest-sum-subject-to-a-constraint-that-the-sum-is-less-than-k




You can do this in  O(nlog(n)) 


First thing to note is that sum of subarray  (i,j]  is just the sum of the first  j  elements less the sum of the first  i  elements. Store these cumulative sums in the array cum. Then the problem reduces to finding   i,j  such that  i<j  and  cum[j]-cum[i]  is as close to  k  but lower than it.


To solve this, scan from left to right. Put the  cum[i]  values that you have encountered till now into a set. When you are processing  cum[j]  what you need to retrieve from the set is the smallest number in the set such which is bigger than  cum[j]-k . This lookup can be done in  O(log n)  using upper_bound. Hence the overall complexity is  O(nlog(n)) .


Here is a c++ function that does the job, assuming that K>0 and that the empty interval with sum zero is a valid answer. The code can be tweaked easily to take care of more general cases and to return the interval itself.


int best_cumulative_sum(int ar[],int N,int K){set<int> cumset;cumset.insert(0);int best=0,cum=0;for(int i=0;i<N;i++){cum+=ar[i];set<int>::iterator sit=cumset.upper_bound(cum-K);if(sit!=cumset.end())best=max(best,cum-*sit);cumset.insert(cum);}return best;}


0 0
原创粉丝点击