【问题标题】:How to find the longest contiguous odd subsequence in Python?如何在 Python 中找到最长的连续奇数子序列?
【发布时间】:2017-07-23 12:17:47
【问题描述】:

例如,我的序列是:[2, 6, 8, 3, 9, 1, 5, 6, 1, 3, 5],那么答案应该是 [3, 9, 1, 5],因为有两个子序列 [1, 3, 5][3, 9, 1, 5]。最长的应该作为答案返回。任何帮助将不胜感激。

【问题讨论】:

  • 你能展示你到目前为止的尝试吗?你具体卡在哪里了?
  • 看看itertools.groupby

标签: python dynamic-programming


【解决方案1】:

您可以使用以下复杂的单线:

from itertools import groupby
from operator import itemgetter

max(map(list,map(itemgetter(1),filter(itemgetter(0),groupby(data,key=lambda x:x&1)))),key=len)

data 输入列表。

让我们先把它分成几个部分:

from itertools import groupby
from operator import itemgetter

tmp = groupby(data,key=lambda x:x&1)  # group by even-odd bursts
tmp = filter(itemgetter(0),tmp)       # filter only bursts of odd numbers
tmp = map(itemgetter(1),tmp)          # obtain the slice of numbers
tmp = map(list,tmp)                   # convert them to lists
result = max(tmp,key=len)             # get the list with the largest length

此算法在 O(n) 中运行,因为它在 data 上执行固定数量的传递(由于 惰性 它实际上只扫描列表一次)列表。所有检查都是 O(1) (对于每个元素检查),或 O(k) 对于每个突发(k 的长度为爆发)。

您可以使用(感谢@PM2Ring)以功能较少的方式重写上述内容:

max((list(g) for k,g in groupby(data,key=lambda x:x&1) if k),key=len)

相当于上面的,但少了pointfree(这是函数式编程中的一个术语)。

【讨论】:

  • 是的,好的。就个人而言,我不会在这里使用itemgetter,我只会使用max((list(g) for k, g in groupby(a, key=lambda n: n % 2) if k), key=len)
  • @PM2Ring:是的。这可能更多是因为太多的函数式编程。前者被认为是“更无积分”。
【解决方案2】:

你可以试试这个:

l = [2, 6, 8, 3, 9, 1, 5, 6, 1, 3, 5]
final_list = []
for i in l:
   new_l = []
   if i%2 == 0:
      final_list.append(new_l)
      new_l = []
   else:
       new_l.append(i)

print(max(final_list, key=len))

输出:

[3, 9, 1, 5]

【讨论】:

  • 我真的不明白你为什么要执行嵌套的for 循环。现在你让它成为一个 O(n^2) 算法。一次通过就足够了。此外,由于[i+1:],您忽略了第一个元素。
  • 这正是我想要的。非常感谢 :) 只是一个更正:第一个 new_l 分配应该在 for 循环之上,否则它会打印一个空列表。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多