Longest Subarray with Sum greater than Equal to K

Given an array of N integers. The task is to find the maximum length subarray such that the sum of all its elements is greater than or equal to K.

Input: arr[]= {-1, 4, -2, -5, 6, -8}, K=0
Output: 5

Explanation: {-1, 4, -2, -5, 6} forms the longest sub array with sum=2.

Discussion :


class Pair{
    private int sum;
    private int index;

    Pair(int sum,int index){
        this.index = index;
        this.sum = sum;
    }

    public int getSum() {
        return sum;
    }
    public int getIndex() {
        return index;
    }
}


import java.util.*;

public class test{

    static int findInd(ArrayList<Pair> preSum, int n, int val) {
        int l = 0, h = n - 1, mid;
        int ans = -1; 
        while (l <= h) { 
            mid = l + (h-l)/2; 
            if (preSum.get(mid).getSum() <= val) { 
                ans = mid; 
                l = mid + 1; 
            } 
            else h = mid - 1; 
        } 
        return ans; 
    } 

    static int largestSub(int arr[], int n, int k) { 

        int maxlen = 0; 
        ArrayList<Pair> preSum = new ArrayList<>();
        int sum = 0; 
        int minInd[] = new int[n];

        for (int i = 0; i < n; i++) { 
            sum = sum + arr[i]; 
            preSum.add(new Pair(sum,i)); 
        } 
  
        Collections.sort(preSum, new Comparator<Pair>() {
            public int compare(Pair s1, Pair s2) {
               int sum1 = s1.getSum();
               int sum2 = s2.getSum();
               if(sum1==sum2) return s1.getIndex() - s2.getIndex();
               return sum1-sum2;
            }
        });

        minInd[0] = preSum.get(0).getIndex(); 
    
        for (int i = 1; i < n; i++) { 
            minInd[i] = Math.min(minInd[i - 1], preSum.get(i).getIndex()); 
        } 
    
        sum = 0; 
        for (int i = 0; i < n; i++) { 
            sum = sum + arr[i]; 
            if (sum > k) maxlen = i + 1; 
            else { 
                int ind = findInd(preSum, n, sum-k-1); 
                if (ind != -1 && minInd[ind] < i) 
                    maxlen = Math.max(maxlen, i - minInd[ind]); 
            } 
        } 
        return maxlen; 
    } 
    
    public static void main(String[] args) {
        int arr[] = {-3 ,-2, -2, 5, -1 }; 
        int n = arr.length; 
        int k = 0;
        //longest subarray whose sum is greater then or equal to k
        System.out.println(largestSub(arr, n, k-1));
    }

}

Time complexity : O(NlogN)
Space : O(N)

Comments

Popular posts from this blog

Search in Rotated Sorted Array

Consistent Hashing