简体   繁体   中英

Longest Snake Sequence in an Array

Question : A set of numbers separated by space is passed as input. The program must print the largest snake sequence present in the numbers. A snake sequence is made up of adjacent numbers such that for each number, the number on the right or left is +1 or -1 of it's value. If multiple snake sequences of maximum length is possible print the snake sequence appearing in the natural input order.

Example Input/Output 1:

Input:

9 8 7 5 3 0 1 -2 -3 1 2

Output:

3 2 1 0 1

Example Input/Output 2:

Input:

-5 -4 -3 -1 0 1 4 6 5 4 3 4 3 2 1 0 2 -3 9

Output:

6 5 4 3 4 3 2 1 0 -1 0 1 2

Example Input/Output 3:

Input:

5 6 7 9 8 8

Output:

5 6 7 8 9 8

I have searched online & have only found references to find a snake sequence when a grid of numbers is given & not an array.

My Solution so far :
Create a 2D Array containing all the numbers from input as 1 value and the 2nd value being the max length sequence that can be generated starting from that number. But this doesn't always generate the max length sequence and doesn't work at all when there are 2 snakes of max length.

Assuming that the order in the original set of numbers does not matter, as seems to be the case in your question, this seems to be an instance of the Longest Path Problem , which is NP-hard.

Think of it that way: You can create a graph from your numbers, with edges between all pairs of nodes that have a difference of one. Now, the longest simple (acyclic) path in this graph is your solution. Your first example would correspond to this graph and path. (Note that there are two 1 nodes for the two ones in the input set.)

在此处输入图片说明

While this in itself does not solve your problem, it should help you getting started finding an algorithm to solve (or approximate) it, now that you know a better/more common name for the problem.


One algorithm works like this: Starting from each of the numbers, determine the "adjacent" numbers and do sort of a depth-first search through the graph to determine the longest path. Remember to temporarily remove the visited nodes from the graph. This has a worstcase complexity of O(2 n ) 1) , but apparently it's sufficient for your examples.

def longest_snake(numbers, counts, path):
    best = path
    for n in sorted(counts, key=numbers.index):
        if counts[n] > 0 and (path == [] or abs(path[-1] - n) == 1):
            counts[n] -= 1
            res = longest_snake(numbers, counts, path + [n])
            if len(res) > len(best):
                best = res
            counts[n] += 1
    return best

Example:

>>> from collections import Counter
>>> numbers = list(map(int, "9 8 7 5 3 0 1 -2 -3 1 2".split()))
>>> longest_snake(numbers, Counter(numbers), [])
[3, 2, 1, 0, 1]

Note that this algorithm will reliably find a maximum "snake" sequence, using no number more often than allowed. However, it may not find the specific sequence that's expected as the output, ie "the snake sequence appearing in the natural input order", whatever that's supposed to mean. To get closer to the "natural order", you might try the numbers in the same order as they appear in the input (as I did with sorted ), but that does not work perfectly, either. Anyway, I'm sure you can figure out the rest by yourself.


1) In this special case, the graph has a branching factor of 2, thus O(2 n ); in the more general case, the complexity would be closer to O(n!).

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