简体   繁体   中英

How to iterate over array of integers to find a sequence based on an O(N) solution?

I saw following question and tried to find an answer for that.

Question:  Given a sequence of positive integers A and an integer T, return whether there is a *continuous sequence* of A that sums up to exactly T
Example
[23, 5, 4, 7, 2, 11], 20. Return True because 7 + 2 + 11 = 20 
[1, 3, 5, 23, 2], 8. Return True  because 3 + 5 = 8
[1, 3, 5, 23, 2], 7 Return False because no sequence in this array adds up to 7

Note: We are looking for an O(N) solution. There is an obvious O(N^2) solution which is a good starting point but is not the final solution we are looking for.

My answer to above question is:

public class Tester {
    public static void main(String[] args) {
        int[] myArray = {23, 5, 4, 7, 2, 11};
        System.out.println(isValid(myArray, 20));
    }

    public static boolean isValid(int[] array, int sum) {
        int pointer = 0;
        int temp = 0;

        while (pointer < array.length)
        {
            for (int i = pointer; i < array.length; i++)
            {
                if (array[i] > sum)
                    break;

                temp += array[i];
                if (temp == sum)
                    return true;
                else if (temp > sum)
                    break;
                // otherwise continue
            }

            temp = 0;
            pointer++;
        }

        return false;
    }
}

I think my answer is O(N^2) which is not acceptable based on Question. Is there a solution based on O(N)?

You only need to loop once actually which is O(N).

Start adding from index 0 and once you exceed the sum start removing from the beginning of the array. if temp falls below sum continue looping.

  public static boolean isValid(int[] array, int sum) {
    int init = 0,temp = 0;

    for (int i = 0; i < array.length; i++) {
      temp += array[i];
      while (temp > sum) {
        temp -= array[init];
        init++;
      }
      if (temp == sum)
        return true;
    }
    return false;
  }

What you should do is to have two indices (start and stop) then you increase stop until the sum is the required (and return true ) or above. Then you increase start until the sum is the required (and return true or below. Then you repeat this until you reach the end of the array. You can update the sum incrementally (add the element when you increase stop and subtract when you increase start ). This ought to be O(N).

Here's an example:

public class t {
    public static void main(String[] args) {
        int[] myArray = {23, 5, 4, 7, 2, 11};
        System.out.println(isValid(myArray, 20));
    }

    public static boolean isValid(int[] array, int sum) {
        int start = 0;
        int stop = 0;
        int tsum = 0;

        while( true )
        {
            if( tsum < sum )
            {
                if( stop >= array.length )
                    break;
                tsum += array[stop];
                stop++;
            }
            else if( tsum > sum )
            {
                tsum -= array[start];
                start++;
            }
            else if( tsum == sum )
                return true;

            // System.out.println(start + " -- " + stop + " => " + tsum);
        }

        return false;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM