HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaMinor

Min sub array size with a given sum

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
withsizearraysubminsumgiven

Problem

How can the time complexity of the following code be improved (assuming it's \$O(N^2)\$)? What about style and patterns?
This code is trying to find the minimum subarray size that adds up to given sum k. Elements should be adjacent.

/**
 * Created by mona on 5/24/16.
 */
public class MinSubArray {

    public static void minSubArray(int[] a, int k){

        int start=-1;
        int end=-1;
        int min=Integer.MAX_VALUE;

        for (int i=0; ik){
                    break;
                }
            }
        }

        if (start==-1 || end==-1){
            System.out.println("No such array exists with sum of "+k);
        }
        while (start<=end){
            System.out.print(a[start]+" ");
            start++;
        }

    }

    public static void main(String[] args){
        int a[] ={1,2,3,-1,2,4,8,9,5,6,-2,-3,10};
        minSubArray(a,5);

    }
}

Solution

1 Coding conventions

The Java coding conventions dictate that any for, if, while construct is preceded by a blank line. So instead of

int dummy = 10;
for (int i = 0; i < dummy; ++i) {
    ...
}


you should write

int dummy = 10;

for (int i = 0; i < dummy; ++i) {
    ...
}


Next, you have no space after the conditions of if statements: Instead of

if (testCondition()){
    ...
}


you should write

if (testCondition()) { // Note the space before '{'!
    ...
}


2 Algorithm

Printing to standard output in an algorithm is a no-no. Suppose you want to use your implementation in a real-world project. Apart from flooding the stdout, you waste time since calling System.out.print* goes down through the Java virtual machine straight to the OS, and is, thus, expensive. So, it would be nicer just return an integer whose value is the index of the leftmost element of the solution.

3 Summa summarum

All in all, I thought about this reimplementation:

public static int minSubArrayV2(final int[] array, final int targetSum) {
    if (targetSum == 0) {
        // Special case: return the index of the first array component whose 
        // value is zero.
        for (int i = 0; i  0) {
        for (int startIndex = 0; startIndex  targetSum) {
                    break;
                } else if (sum == targetSum) {
                    return startIndex;
                }
            }
        }
    } else {
        for (int startIndex = 0; startIndex < array.length; ++startIndex) {
            int sum = 0;

            for (int i = startIndex; i < array.length; ++i) {
                sum += array[i];

                if (sum < targetSum) {
                    break;
                } else if (sum == targetSum) {
                    return startIndex;
                }
            }
        }
    }

    return -1;
}


Hope that helps.

A note

I spent about two hours thinking about how to improve the time complexity of your algorithm, and did not find any opportunity. However, you could spent \$\Theta(N^2)\$ for preprocessing the array, after which you can do queries in constant time. Consider the following:

public static Map preprocessArray(final int[] array) {
    final Map map = new HashMap<>();

    for (int startIndex = 0; startIndex  map = preprocessArray(array);
    System.out.println(map.get(6));
}

Code Snippets

int dummy = 10;
for (int i = 0; i < dummy; ++i) {
    ...
}
int dummy = 10;

for (int i = 0; i < dummy; ++i) {
    ...
}
if (testCondition()){
    ...
}
if (testCondition()) { // Note the space before '{'!
    ...
}
public static int minSubArrayV2(final int[] array, final int targetSum) {
    if (targetSum == 0) {
        // Special case: return the index of the first array component whose 
        // value is zero.
        for (int i = 0; i < array.length; ++i) {
            if (array[i] == 0) {
                return i;
            }
        }

        return -1;
    }

    if (targetSum > 0) {
        for (int startIndex = 0; startIndex < array.length; ++startIndex) {
            int sum = 0;

            for (int i = startIndex; i < array.length; ++i) {
                sum += array[i];

                if (sum > targetSum) {
                    break;
                } else if (sum == targetSum) {
                    return startIndex;
                }
            }
        }
    } else {
        for (int startIndex = 0; startIndex < array.length; ++startIndex) {
            int sum = 0;

            for (int i = startIndex; i < array.length; ++i) {
                sum += array[i];

                if (sum < targetSum) {
                    break;
                } else if (sum == targetSum) {
                    return startIndex;
                }
            }
        }
    }

    return -1;
}

Context

StackExchange Code Review Q#129241, answer score: 5

Revisions (0)

No revisions yet.