Longest consecutive sequence of ascending, descending, or equal integers Given an array of integers, find the longest consecutive sequence, where a sequence is defined as being either (strictly) ascending, (strictly) descending, or all-equal.

836926 then has the longest sequence 369, which happens to be ascending. 241455556 has the longest sequence 5555, which happens to be all equal.

Please comment on the algorithm (correct? complexity?) and how it can be improved.

#include &lt;iostream&gt;
#include &lt;vector&gt;

int sign(int someInt)
{
    if (someInt &gt; 0) { return 1; };
    if (someInt &lt; 0) { return -1; };
    return 0;
}

bool isSequence(int a, int b, int c)
{
    if (sign(a - b) == sign(b - c))
    {
        return true;
    }

    return false;
}

void findSeq(const std::vector&lt;int&gt; &amp;vect)
{
    int maxLength = 0;
    int startingIndex = 0;

    int currentLength = 2;
    int findIndex = 0;

    for (int i = 0; i &lt; vect.size() - 2; i++)
    {

        if (isSequence(vect[i], vect[i + 1], vect[i + 2]))
        {
            currentLength++;
            if (currentLength &gt; maxLength)
            {
                startingIndex = i - findIndex;
                maxLength = currentLength;
            }
            findIndex++;
        }

        else
        {
            findIndex = 0;
            currentLength = 2;
        }
    }

    for (int j = startingIndex; j &lt; startingIndex + maxLength; j++)
    {
        std::cout &lt;&lt; vect[j];
    }

}
The code is generally good and clear.  I like the names you've used for your variables - it's very obvious what each does, with the possible exception of findIndex.

There's an issue with the problem statement (which might not be your fault): it doesn't say what to do if there's more than one "longest" sequence.  In this code, it appears that we use the first match if there's another of the same length; it's worth writing a comment to be clear that this is what we want (and including such a case in the tests, so that we know if that changes).



isSequence is a bit more long-winded than it needs to be.  This pattern is redundant:

if (condition)
    return true;
else
    return false;


It can always be replaced with

return condition;




In findSeq itself, we're doing pretty well.  I get a compiler warning about comparing (signed) i against (unsigned) vect.size(); that's easily fixed by changing i to be a std::size_t instead of an int.  Most of the other int variables would be better represented as std::size_t, too.

One thing we might want to do is to use iterators rather than indexes, to give us an opportunity to work with different collections in future.  And instead of printing to std::cout, we might want to return the start and end iterators of the longest matching sequence.  (If we do print the values, it's a good idea to separate them from each other, otherwise we can't tell 33,3 from 3,3,3, for example).

If we're using iterators, we'll want to remember the previous and ante-previous values, because we can't necessarily go back to them.  Equivalently, we can remember the previous value and the direction of difference.

I don't know if this is beyond your current knowledge, but this is what I came up with when I followed my own suggestions, and took it a little further to work generically as a template:

#include &lt;iterator&gt;
#include &lt;utility&gt;

// return the sign of a-b (or the sign of a, if b is defaulted)
// result: -1 if a&lt;b, 0 if a==b, +1 if a&gt;b
template&lt;typename T&gt;
int compare(T a, T b = {})
{
    // This is a "clever" way of determining the sign.  Some
    // compilers recognise this idiom and reduce it to a single
    // instruction.
    return (a &gt; b) - (a &lt; b);
}

template&lt;typename ForwardIterator&gt;
std::pair&lt;ForwardIterator,ForwardIterator&gt;
findSeq(const ForwardIterator first, const ForwardIterator last)
{
    if (first == last) {
        // empty range -&gt; empty result
        return { first, first };
    }

    auto best_start = first;
    auto best_end = first;
    std::size_t best_length = 0;

    auto current_start = first;
    auto previous = first;
    int current_direction = 0;
    std::size_t current_length = 0;

    auto const update_best = [&amp;](ForwardIterator end){
        best_start = current_start;
        best_end = end;
        best_length = current_length;
    };

    for (auto it = std::next(first);  it != last;  ++it) {
        const auto new_direction = compare(*previous, *it);

        if (new_direction == current_direction) {
            ++current_length;
        } else {
            if (current_length &gt; best_length) {
                update_best(it);
            }
            current_direction = new_direction;
            current_start = previous;
            current_length = 1;
        }

        previous = it;
    }

    if (current_length &gt; best_length) {
        update_best(last);
    }

    return { best_start, best_end };
}

// provide an interface compatible with the original
template&lt;typename Collection&gt;
auto findSeq(const Collection&amp; c)
{
    using std::begin;
    using std::end;

    return findSeq(begin(c), end(c));
}




#include &lt;array&gt;
#include &lt;iostream&gt;
#include &lt;forward_list&gt;
#include &lt;vector&gt;

template&lt;typename ForwardIterator&gt;
void printSeq(std::pair&lt;ForwardIterator,ForwardIterator&gt; range)
{
    auto [first,last] = range;
    for (auto it = first;  it != last;  ++it)
        std::cout &lt;&lt; *it &lt;&lt; ' ';
    std::cout &lt;&lt; std::endl;
}

int main()
{
    printSeq(findSeq(std::vector{8,3,6,9,2,6,12}));
    printSeq(findSeq(std::array{-0.1, -0.2, -0.3, -0.4, 0.1, 0.2, 0.3, -1.0}));
    printSeq(findSeq(std::forward_list&lt;std::string&gt;{
                "foo", "bar", "bar", "bar", "baz", "quux"}));
}