我想写一个函数,在线性时间内找到列表中最长的序列a_0〈= a_1〈= ...〈= a_k〉= a_(k+1)〉= ...〉= a_n。这看起来很容易,但没有嵌套的for循环,我就陷入了困境。我的想法如下:
if len(L) == 0 or len(L) == 1:
return len(L)
if all(L[i] == L[0] for i in range(len(L)-1)):
return len(L)
left = [1] * len(L)
right = [1] * len(L)
count = 1
for i in range(len(L)-1):
if L[i] <= L[i+1]:
count += 1
left[i+1] = count
else:
count = 1
left[i+1] = count
count = 1
for i in range(len(L)-1, -1, -1):
if L[i] <= L[i-1]:
count += 1
right[i-1] = count
else:
count = 1
right[i-1] = count
idx_left = left.index(max(left))
idx_right = right.index(max(right))
if max(max(left), max(right)) == max(left) and idx_left == len(left) - 1:
return max(left)
elif max(max(left), max(right)) == max(right) and idx_right == 0:
return max(right)
if idx_left == idx_right:
return max(left) + max(right) - 1
elif idx_left < idx_right:
return max(left) + max(right[idx_left:])
else:
return max(left[:idx_right]) + max(right)
return max(max(left) + max(right[idx_left:]), max(right) + max(left[:idx_right]))
这个方法有时可以工作,但是我发现有几种情况会产生不正确的输出。你知道如何修复这个问题吗?
print(sequence([10,9,8,7,6,5,4,3,2,1])) # 10
print(sequence([1,2,3,4,5,6,7,8,9,10])) # 10
print(sequence([1,2,3,4,5,6,7,8,9,10,9,8,7,6,5,4,3,2,1])) # 19
print(sequence([0,0,0,0,0,0,0,0,0,0])) # 10
print(sequence([0,0,0,0,0,0,0,0,0,1])) # 10
# These cases are not working yet
print(sequence([1,0,0,0,0,0,0,0,0,1])) # 10
print(sequence([1,1,0,0,0,0,0,0,0,1])) # 10
print(sequence([1,1,1,0,0,0,0,0,0,2])) # 9
3条答案
按热度按时间jfgube3f1#
你可以试试这个:
它给出:
3yhwsihp2#
试着计算两个值之间的差,我不确定它对每种情况都有效,但这是一个o(n)的开始,
我在结果中添加了1,因为它对比较进行计数,所以最后一个值不会被计数
vshtjzan3#
你可以考虑分组后相同值的增加/减少状态,并跟踪之前的长度,其复杂度为O(n),只需对输入进行一次处理:
输出:
7
itertools.groupby
只是为了避免处理连续的相同值而提供的一种方便,但您不必使用它,可以自己跟踪这些值。*其他例子:
重构代码
这与上面的逻辑完全相同,但是测试已经被组合,中间变量被移除,等等。