1

Lets say we have an array of positive numbers and we were given a value M. Our goal is to find if there is a consecutive sub sequence in the array of positive numbers such that the sum of the sequence is exactly equal to sum M. If A[1],A[2],....A[n] is an array then we have to find if there exist i and j such that A[i]+...+A[j] = M.

I am trying to get the O(n) solution using greedy approach.

2
  • Are the numbers both positive and negative? Commented Feb 24, 2016 at 16:47
  • They are only positive. Commented Feb 24, 2016 at 16:47

5 Answers 5

6

I believe you can solve this in linear time with a pointer chasing algorithm.

Here's the intuition. Start off a pointer at the left side of the array. Keep moving it to the right, tracking the sum of the elements you've seen so far, until you either hit exactly M (done!), your total exceeds M (stop for now, adding in more elements only makes it worse), or you hit the end of the array without reaching at least M (all the elements combined are too small). If you do end up in a case where the sum exceeds M, you can be guaranteed that no subarray starting at the beginning of the array adds up to exactly M, since you tried all of them and they were either too small or too big.

Now, start a second pointer at the first element and keep advancing it forward, subtracting out the current element, until you either get to exactly M (done!), you reach the first pointer (stop for now), or the total drops below M (stop for now). All the elements you skipped over with this pointer can't be the starting point of the subarray you're looking for. At this point, start marching the first pointer forward again.

Overall, each pointer advances at most n times and you do O(1) work per step, so this runs in time O(n). Plus, it uses only O(1) space, which is as good as it's going to get!

Sign up to request clarification or add additional context in comments.

Comments

2

This is a standard two pointer problem. First of all, create an array, prefix that will store the prefix sum of the given array, say arr.

So

prefix[i] = arr[1] + .. + arr[i] 

Start with two pointers, lower and upper. Initialize them as

lower = 0 upper = 1 

(Note: Initialize prefix[0] to 0)

Now, try to understand this code:

lower = 0, upper = 1; while(upper <= n) { // n is the number of elements if(prefix[upper] - prefix[lower] == m) { return true; } else if(prefix[upper] - prefix[lower] > m) { lower++; } else { upper++; } } return false; 

Here we are using the fact that the array consists of positive integers, hence prefix is increasing

4 Comments

Answer looks correct to me. To make the code slightly cleaner, you could remove the first line as it is not used.
Lets suppose array is {9,1,3,7,2} and required sum is 11 (1,3,7 gives this). Then prefix array is {0,9,10,13,20,22} . Now if we run your algo then we won't get answer. So I am confused whether the prefix array I made is the same logic you are referring?
@faizan yes you are right, I have updated the code. Thanks for pointing it out
@bk2dcradle : This is correct, though if you notice, the accepted answer does the same as well. The difference being that you have pre-computed the prefix sums while accepted answer computes it on the fly by adding/subtracting from previous prefix sum. Also accepted answer needs O(1) space. Nice answer and pseudo-code, easier to understand, but not space efficient. My 2 cents.
0

Assume that the subarray with indices X ≤ i < Y might be the solution.

You start with X = 1, Y= 1, sum of elements = 0.

As long as the sum is less than M, and Y <= n, increase the sum by array [Y] and replace Y with Y + 1.

If the sum is equal to M, you found a solution.

If the sum is less than M, you remove array elements at the start: As long as the sum is greater than M, subtract array [X] from the sum and replace X with X + 1. If the sum became equal to M, you have a solution. Otherwise you start with the first loop.

Comments

0

(edited: see templatetypedef's comment)

Use the two indices approach: increase the lower index if subsequence too small otherwise increase higher index.

Example:

void solve(int *a, int n, int M) { if (n <= 0) return; int i, j, s; i = 0, j = 0, s = a[j]; while (j < n) { if (s == M) { printf("%dth through %dth elements\n", i + 1, j + 1); return; } else if (s < M) { j++; s += a[j]; } else { s -= a[i]; i++; } } } 

1 Comment

I don't actually think you need that array. You can do this in O(1) space.
0
public class FindSumEquals { public static void main(String[] args) { int n = 15; System.out.println("Count is "+ findPossible(n)); } private static int findPossible(int n) { int temp = n; int arrayLength = n / 2 + 2; System.out.println("arrayLength : " + arrayLength) ; int a [] = new int[arrayLength]; int count = 0; for(int i = 1; i < arrayLength; i++){ a[i] = i + a[i - 1]; } int lower = 0, upper = 1; while(upper <= arrayLength - 1) { if(a[upper] - a[lower] == temp) { System.out.println("hello - > " + ++lower + " to "+ upper); upper++; count++; } else if(a[upper] - a[lower] > temp) { lower++; } else { upper++; } } return count; } } 

1 Comment

Hello and welcome to SO! While this code may answer the question, providing additional context regarding how and/or why it solves the problem would improve the answer's long-term value. Please read the tour, and How do I write a good answer?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.