views:

182

answers:

4

Given this array

int [] myArray = {5,-11,2,3,14,5,-14,2};

I must be able to return 3 because the longest down sequence is 14,5,-14. What's the fastest way to do this?

PS: Down sequence is a series of non-increasing numbers.

+1  A: 

Just make one pass through the list of numbers. Pseudocode:

bestIndex = 0
bestLength = 0

curIndex = 0
curLength = 1

for index = 1..length-1
   if a[index] is less than or equal to a[index-1]
       curLength++
   else 
       //restart at this index since it's a new possible starting point
       curLength = 1
       curIndex = index

   if curLength is better than bestLength
       bestIndex = curIndex
       bestLength = curLength

next          

Note: You can ditch any line containing bestIndex or curIndex if you don't care about knowing where that subsequence occurs, as seen in Gary's implementation.

Mark Peters
He said "non-increasing" though, this finds the length of the longest decreasing sequence.
oksayt
Thanks @oksayt, corrected. I don't think that changes the algorithm any, just the comparison.
Mark Peters
Counterexample [1,1,0,1,1] The longest non increasing is 4 long, your algorithm returns 3.
piccolbo
@piccolbo: I don't understand.... you increase going from 0 to 1. What do you think the 4-length subsequence is? Maybe I don't understand the problem, but your "counterexample" makes no sense to me.
Mark Peters
Oh, I see, you have a different interpretation of the problem. I don't think there's any evidence for your interpretation, given in the example the OP gave there are many different non-contiguous sequences that come earlier;t he went out of his way to give the contiguous one as the sample solution.
Mark Peters
You are right, I just made the problem into something interesting to me.
piccolbo
+2  A: 

another implementation in python:

def longest_down_sequence(seq):
    max = 0
    current_count = 0
    last = None
    for x in seq:
        if x <= last: current_count += 1
        else: current_count = 1
        if current_count > max: max = current_count
        last = x
    return max
Gary
Ah yes I forgot to mention on my answer that you save two variables if you don`t care in the end *where* the subsequence occurred.
Mark Peters
@Gary: Off topic - I've just begun learning python so this example was a great one to get a hang of loops! Thanks.
Sagar V
yea, the for is a for-each in reality. If you want to do a for like usual do "for x in range[0,len(seq)]" and then you can do stuff to seq[x]
Gary
+1  A: 

In java:

    int [] myArray = {5,-11,2,3,14,5,-14,2};
    int downSequence = 1;
    int longestDownSequence = 1;
    for(int i = 1; i < myArray.length; i++) {
        if(myArray[i] <= myArray[i-1]) downSequence++;
        else {
            if(downSequence > longestDownSequence)
                longestDownSequence = downSequence;
            downSequence = 1;
        }
    }
    if(downSequence > longestDownSequence)
        longestDownSequence = downSequence;
    System.out.println(longestDownSequence);

Since you're asking for fastest or better performance, only check for the longest down sequence just before you reset the counter. Never on each iteration. However, you have to check again after the loop in case the longest sequence is at the end of the array.

Adrian M
This is what i have too, submitted to my school auto marker, didnt go through, i think we miss out some cases which we didnt handle here
Derek Long
The only thing I could think of is if it's an empty array. Should it return zero then?
Adrian M
Btw, I edited the code to include equals sequence as a down sequence as per your defition. I missed that one.
Adrian M
I specifically didn't write my answer in java because it looks like a simple homework problem :-).
Gary
A: 

As Bill above said, this is essentially longest increasing subsequence. See the wikipedia entry for the optimal solution. This is quoted from there with small changes to work for the nondecreasing case

 L = 0
 for i = 1, 2, ... n:
    binary search for the largest positive j ≤ L such that X[M[j]] >= X[i] (or set j = 0 if no such value exists)
    P[i] = M[j]
    if j == L or X[i] >= X[M[j+1]]:
       M[j+1] = i
       L = max(L, j+1)

See counterexample to other proposed solution in my comment above.

piccolbo
Different interpretations, but given the sample input and output the OP gave, I'd say there's no more evidence this is what he's looking for. See my answer.
Mark Peters