簡體   English   中英

數字列表中最長的蛇序列

[英]Longest Snake Sequence in a list of numbers

問題:一組由空格分隔的數字作為輸入傳遞。 程序必須打印數字中存在的最大的蛇序列。 蛇形序列由相鄰的數字組成,因此對於每個數字,左側或右側的數字為其值的+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

我通過以下鏈接在Python中找到了一個程序: “數組中的最長蛇” ,如下所示,但它無法滿足以下測試用例。 如問題中提到的,如果有兩個或更多最大長度的序列,程序必須打印以自然輸入順序出現的蛇形序列。 我懷疑這是造成問題的參數。

輸出應該是該程序所顯示的輸出,因為相異點是8和10。 10,但這不是預期的輸出。

"""
Test case Input:
4 3 1 6 7 8 8 21 7 8 9 13 -1 2 14 9 10 11 10 9

Expected Output:
6 7 8 7 8 9 10 11 10 9 8 9

Your Program Output:
6 7 8 7 8 9 8 9 10 9 10 11
"""

from collections import Counter
def longest_snake(numbers,counts,path):
        best = path
        for n in sorted(counts, key = numbers.index, reverse=True):
                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
if __name__ == '__main__':
        numbers = list(map(int, raw_input().split()))
        output = longest_snake(numbers,Counter(numbers),[])[::-1]
        print(' '.join(map(str,output)))

我對算法做了些微改動。 它仍然不能滿足所有測試用例,但與我理解的“自然輸入順序”非常接近。

def longest_snake(numbers, counts, path, pos=0):
    visited = set()                                # keep track of visited nodes
    best, total = path, pos                        # best path and best pos
    for i in range(len(numbers)):                  # for one more round...
        n = numbers[(pos + i) % len(numbers)]      # wrap around edges, get n
        if n not in visited and counts[n] > 0 and (path == [] or abs(path[-1] - n) == 1):
            visited.add(n)
            counts[n] -= 1
            res, t = longest_snake(numbers, counts, path + [n], pos + i)
            if len(res) > len(best) or (len(res) == len(best) and t < total):
                best, total = res, t               # longer path or fewer steps
            counts[n] += 1
    return best, total                             # return both path and total steps

現在是這樣的:

  • 它跟蹤輸入列表( pos )中的當前位置
  • 遞歸時,它將繼續在該位置,將pos + i傳遞給遞歸調用,因此首先嘗試對數字進行“塊化”
  • 如果pos + i大於輸入的長度,則繞到開頭
  • 如果兩條蛇形路徑的長度相同,則它所采用的路徑的總位置較低,即為此,輸入時需要較少的前進,並且到起點的“纏繞”較少

正如我所說,它更接近“自然輸入順序”,但仍不完美。 這是一個例子:

6 5 4 3 4 3 2 1 0 -1 0 1 2  # expected output
4 5 4 3 4 3 2 1 0 -1 0 1 2  # my output 

最后,所有這些都歸結為如何定義“自然輸入順序”。 以第一個測試用例為例,即9 8 7 5 3 0 1 -2 -3 1 2 :此版本的代碼產生1 0 1 2 3 ,但預期為3 2 1 0 1 但為什么? 我的結果在輸入( 1 2 )中有一對彼此相鄰的數字,而預期的輸出則沒有,而我的“步數”也較少(兩次,然后是3 ,而預期的大約兩次,直到1 s之一。

或者換句話說:您可以采用我的算法並將條件更改為此:

if len(res) > len(best) or (len(res) == len(best) and isMoreOrdered(numbers, res, best)):`

如果您可以定義函數isMoreOrdered(numbers, new_path, old_path) ,那么您就完成了。 但是,從幾個例子和問題的措辭來看,我當然不能說清楚。

無論如何,也許這給了您一些想法,您可以自己找出其余的想法。

暫無
暫無

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

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