LeetCode – Minimum Size Subarray Sum (Java)

Given an array of n positive integers and a positive integer s, find the minimal length of a subarray of which the sum ≥ s. If there isn’t one, return 0 instead.

For example, given the array [2,3,1,2,4,3] and s = 7, the subarray [4,3] has the minimal length of 2 under the problem constraint.

Analysis

We can use 2 points to mark the left and right boundaries of the sliding window. When the sum is greater than the target, shift the left pointer; when the sum is less than the target, shift the right pointer.

Java Solution – two pointers

A simple sliding window solution.

public int minSubArrayLen(int s, int[] nums) {
    if(nums==null || nums.length==1)
        return 0;
 
    int result = nums.length;
 
    int start=0;
    int sum=0;
    int i=0;
    boolean exists = false;
 
    while(i<=nums.length){
        if(sum>=s){
            exists=true; //mark if there exists such a subarray 
            if(start==i-1){
                return 1;
            }
 
            result = Math.min(result, i-start);
            sum=sum-nums[start];
            start++;
 
        }else{
            if(i==nums.length)
                break;
            sum = sum+nums[i];
            i++;    
        }
    }
 
    if(exists)
        return result;
    else
        return 0;
}

Similarly, we can also write it in a more readable way.

public int minSubArrayLen(int s, int[] nums) {
    if(nums==null||nums.length==0)
        return 0;
 
    int i=0; 
    int j=0;
    int sum=0;
 
    int minLen = Integer.MAX_VALUE;
 
    while(j<nums.length){
        if(sum<s){
            sum += nums[j];
            j++;        
        }else{
            minLen = Math.min(minLen, j-i);
            if(i==j-1)
                return 1;
 
            sum -=nums[i];
            i++;
        }
    }
 
    while(sum>=s){
        minLen = Math.min(minLen, j-i);
 
        sum -=nums[i++];
    }
 
    return minLen==Integer.MAX_VALUE? 0: minLen;
}

20 thoughts on “LeetCode – Minimum Size Subarray Sum (Java)”

  1. In my mentioned solution, I don’t care whether the input array is sorted or not.
    – First, I calculated the prefix sum array which will contain the sum starting from 0 to i for 0 <= i = the given sum in the problem.
    – Finally, To check the direction of the binary search step, I am iterating over all possible subarrays with length equal to mid, and decide whether to go left or right according to the following explanation.

    As, you can see the second step is suitable to apply binary search on it, as if we have a sub array of length l1 and its sum >= the given sum, then we don’t need to check lengths > l1, and the reverse is correct as well (If we can’t find a sub array of length l2 and its sum >= the given sum, then it means we can’t find another subarray with a length less than l2, so we will ignore all lengths < l2).

  2. I don’t understand how can this be done using a binary search.
    The input array of numbers isn’t sorted.

  3. So the logic behind my solution is a moving window, having a length, where it ends (the traversed `i`) and the sum.


    int minLengthSubarraySum(int[] nums, int s)
    {
    if (nums == null || nums.length == 0) return 0;

    int minLength = Integer.MAX_INT;
    int curLength = 0;
    int sum = 0;

    for (int i = 0 ; i = s)
    {
    currLength--;
    sum -= nums[i-currLength];
    }
    }

    return minLength == Integer.MAX_INT ? 0 : minLength;
    }

  4. O(n) solution using two pointers approach

    class Solution {
    public:
    int minSubArrayLen(int s, vector& nums) {
    if(nums.size() == 0) return 0;
    int startPosition = 0, endPosition = -1, sum = 0, minLen = INT_MAX;
    for(int i = 0; i = s) {
    sum -= nums[startPosition];
    startPosition++;
    }
    if(sum >= s) minLen = min(minLen, endPosition - startPosition + 1);
    }
    return minLen != INT_MAX ? minLen : 0;
    }
    };

  5. O(n log n) solution using Binary Search

    class Solution {
    public:
    int minSubArrayLen(int s, vector& nums) {
    if(nums.size() == 0) return 0;
    /* build prefix sum array */
    vector sum(nums.size());
    for(int i = 0; i 0 ? sum[i - 1] : 0);
    /* binary search on the minimium length */
    int L = 1, R = nums.size(), ans = 0;
    while(L <= R) {
    int mid = (L + R) / 2;
    /* check if the length mid is valid */
    bool flag = false;
    for(int i = 0; i + mid = s;
    if(flag) break;
    }
    if(flag) {
    ans = mid;
    R = mid - 1;
    }
    else {
    L = mid + 1;
    }
    }
    return ans;
    }
    };


  6. var arr = [2,3,1,2,4,3]
    var s = 7

    sum = arr[0] + arr[1]
    for(var i=0, j = 1 ; i < j && j< arr.length;){
    if(sum < s){
    j++
    sum += arr[j]
    }
    else {
    i++
    sum -= arr[i]

    }
    }

    arr.slice(i,j)

  7. Yes… It should be O(n), as both the ends of the window would slide through every number only once.

  8. Hi is my solution right?

    public static int minSizeSubArray(int[] arrA, int target){
    if(arrA == null || arrA.length == 0){
    throw new IllegalArgumentException(“”);
    }
    int index = 0;
    int result = Integer.MAX_VALUE;
    int sum = 0;
    for(int i = 0; i target){
    sum = sum – arrA[index];
    index++;
    }
    if(sum == target){
    result = Math.min(result, (i – index)+1);
    sum = sum – arrA[index];
    index++;
    }
    }
    return result;
    }

  9. My solution using Java’s cousin. Scala.

    def minSizeSubArraySum(xs: List[Int], s: Int): Int = {

    def loop(step: Int): Int =
    if (xs.sliding(step).toList.exists(_.sum >= s)) step
    else loop(step + 1)

    if (xs.sum >= s) loop(1) else 0

    }

  10. My solution using Java’s cousin. Scala.

    def minSizeSubArraySum(xs: List[Int], s: Int): Int = {

    def loop(step: Int): Int =
    if (xs.sliding(step).toList.exists(_.sum >= s)) step
    else loop(step + 1)

    if (xs.sum >= s) loop(1) else 0

    }

  11. I want to share my solution here. I think it’s more concise 🙂

    public int minSubArrayLen(int s, int[] nums) {
    if (nums == null || nums.length == 0 || s <= 0) return 0;
    int min = Integer.MAX_VALUE;
    int i = 0, sum = 0;
    for (int j = 0; j = s) {
    min = Math.min(min, j – i + 1);
    sum -= nums[i++];
    }
    }
    return min == Integer.MAX_VALUE ? 0 : min;
    }

  12. No. Sorting is not allowed here since that will alter the original arrangement of the numbers in the array. There is an implicit requirement that the initial order of the numbers in the array be preserved. Sorting will violate that requirement.

  13. Yeah, looks like a sort is required.

    For instance, array[-1, 1, 2, 1, 2, 1], sum = 4, returns 3 based on above algorithm.

    But the same algo with the array being sorted returns the correct answer 2, as the sum of array [2, 2] is >= 4.

Leave a Comment