簡體   English   中英

陣列中最長的蛇序列

[英]Longest Snake Sequence in an Array

問題:一組由空格分隔的數字作為輸入傳遞。 程序必須打印數字中存在的最大的蛇序列。 蛇形序列由相鄰的數字組成,因此對於每個數字,左側或右側的數字為其值的+1或-1。 如果可能有多個最大長度的蛇形序列,請打印以自然輸入順序出現的蛇形序列。

輸入/輸出示例1:

輸入:

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

輸出:

3 2 1 0 1

輸入/輸出示例2:

輸入:

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

輸出:

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

輸入/輸出示例3:

輸入:

5 6 7 9 8 8

輸出:

5 6 7 8 9 8

我在網上搜索過&僅找到了給定數字網格而不是數組時找到蛇序列的參考。

到目前為止我的解決方案:
創建一個2D數組,其中包含來自輸​​入的所有數字作為1值,第二個值是可以從該數字開始生成的最大長度序列。 但是,這並不總是生成最大長度序列,並且當有兩條最大長度的蛇時根本不起作用。

假設原始數字集中的順序無關緊要,就像您所提的問題一樣,這似乎是NP難的最長路徑問題的一個實例。

可以這樣考慮:您可以根據數字創建一個圖,所有對節點之間的邊之間的差為1。 現在,此圖中最長的簡單(非循環)路徑就是您的解決方案。 您的第一個示例將與此圖和路徑相對應。 (請注意,輸入集中的兩個節點有兩個1節點。)

在此處輸入圖片說明

盡管這本身並不能解決您的問題,但現在您知道該問題的更好/更通用的名稱,它應該可以幫助您開始尋找一種算法來解決(或近似)它。


一種算法的工作方式如下:從每個數字開始,確定“相鄰”數字,然后對圖形進行某種深度優先搜索,以確定最長路徑。 記住暫時從圖中刪除訪問的節點。 這具有O(2 n 1)的最壞情況復雜度,但顯然對於您的示例而言已足夠。

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

例:

>>> 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]

請注意,此算法將可靠地找到最大的“蛇形”序列,使用的次數不超過允許的次數。 但是,它可能找不到期望作為輸出的特定序列,即“按自然輸入順序出現的蛇形序列”,無論這意味着什么。 為了更接近“自然順序”,您可以按與輸入中出現的順序相同的順序嘗試數字(就像我對sorted所做的那樣),但這也不完美。 無論如何,我相信您可以自己解決其余的問題。


1)在這種特殊情況下,圖的分支因子為2,因此O(2 n ); 在更一般的情況下,復雜度將接近O(n!)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM