问题:以空格分隔的一组数字作为输入传递。程序必须打印数字中存在的最大蛇序列。蛇序列由相邻的数字组成,因此对于每个数字,右侧或左侧的数字是它的值的+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程序: "Longest Snake in an array" 如下所示,但未能满足以下测试用例。如在问题中提到的,在两个或更多个最大长度序列的情况下,程序必须打印出现在自然输入顺序中的蛇序列。我怀疑这是造成问题的参数。
输出应该是这个程序显示的内容,因为差异点是8和10.(如果我对自然顺序的含义没有错)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)))
答案 0 :(得分:0)
我的算法略有不同。它仍然不能满足所有测试用例,但它更接近我所理解的“自然输入顺序”。
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
)中彼此相邻,而预期的输出没有,我的也有更少的“步数”(两次左右,然后到{{1}虽然预期有两次,但最多有一次3
s。。
或者换句话说:您可以使用我的算法并将条件更改为:
1
如果您可以定义函数if len(res) > len(best) or (len(res) == len(best) and isMoreOrdered(numbers, res, best)):`
,那么您就完成了。但是从几个例子和问题的措辞来看,我当然无法分辨。
无论如何,也许这给了你一些想法,你可以自己找出其余的。