Python 在无序列表中查找最长的有序序列
我试图在无序列表中找到最长的序列并返回它们的索引。还有改进的余地吗?我怎样才能找出最坏的运行时间?我对算法和运行时间非常陌生。谢谢Python 在无序列表中查找最长的有序序列,python,algorithm,Python,Algorithm,我试图在无序列表中找到最长的序列并返回它们的索引。还有改进的余地吗?我怎样才能找出最坏的运行时间?我对算法和运行时间非常陌生。谢谢 def find_longest_array(array): start = 0 end = 0 for left in range(len(array)): for right in range(left + 1, len(array)): sub_array = array[left:right+1
def find_longest_array(array):
start = 0
end = 0
for left in range(len(array)):
for right in range(left + 1, len(array)):
sub_array = array[left:right+1]
if sorted(sub_array) == sub_array:
if len(sub_array) > end - start:
start, end = left, right
if end == len(array):
return start, end
else:
break
return start, end
您的程序在O(n^3 log n)时间内运行,这是非常低效的
我们如何得出O(n^3 logn)的数字
这是一种线性时间方法 让
dp[i]
指示在i
位置结束的最长有序序列
然后:
dp[i]
可以由
- 继续以
结尾的上一个序列(仅当i-1
以保持顺序时才可能)arr[i]>=arr[i-1]
- 或者在这一点开始一个新的有序序列
i
≠ 0
最后,返回所有dp[i]
中的最大值
如果要返回最大数组的实际左右边界,可以从i
向后迭代,其中i
是最大的dp[i]
事实上,您可以完全取消
dp
,只需跟踪当前序列的长度以及迄今为止看到的最大序列的长度和位置
但我觉得这种方法更容易摸索,也更容易正确编写。您的程序在O(n^3 log n)时间内运行,这是非常低效的
我们如何得出O(n^3 logn)的数字
这是一种线性时间方法 让
dp[i]
指示在i
位置结束的最长有序序列
然后:
dp[i]
可以由
- 继续以
结尾的上一个序列(仅当i-1
以保持顺序时才可能)arr[i]>=arr[i-1]
- 或者在这一点开始一个新的有序序列
i
≠ 0
最后,返回所有dp[i]
中的最大值
如果要返回最大数组的实际左右边界,可以从i
向后迭代,其中i
是最大的dp[i]
事实上,您可以完全取消
dp
,只需跟踪当前序列的长度以及迄今为止看到的最大序列的长度和位置
但我觉得这种方法更容易摸索,更容易正确书写。我仍然想回答这个问题,我没有足够的代表发表评论。允许这样做吗 是的,还有改进的余地,您在内部循环上的迭代时间超过了必要的时间,并且重复对整个内部列表进行排序 改进: 首先,一次只需要比较两个值(这个值和下一个值)。第二,一旦您发现一些不一致的东西,您就可以打破嵌套循环。 最后一点只是为了调用更少的函数:我个人喜欢使用python的enumerate而不是range(len):
list=[1,5,78,2,3,6,8,1,7,2,9,3,7,2]
打印(列表)
长度=0
对于索引,枚举(列表)中的项:
a=项目
对于index2,枚举中的以下内容(列表[索引:):
b=以下
如果已排序([a,b])!=[a,b]:#在这里进行比较,寻找突破模式
如果index2>长度:
长度=index2
开始=索引
打破
a=b#更新当前值以继续
打印(“序列{}长,介于{}和{}之间”。格式(长度、开始、开始+长度-1))
打印(列表[开始:开始+长度])
输出:
[1, 5, 78, 2, 3, 6, 8, 1, 7, 2, 9, 3, 7, 2]
Sequence 4 long, between 3 and 6
[2, 3, 6, 8]
但我确信其中有一个while循环解决方案;) 我仍然想回答这个问题,但我没有足够的代表发表评论。允许这样做吗 是的,还有改进的余地,您在内部循环上的迭代时间超过了必要的时间,并且重复对整个内部列表进行排序 改进: 首先,一次只需要比较两个值(这个值和下一个值)。第二,一旦您发现一些不一致的东西,您就可以打破嵌套循环。 最后一点只是为了调用更少的函数:我个人喜欢使用python的enumerate而不是range(len):
list=[1,5,78,2,3,6,8,1,7,2,9,3,7,2]
打印(列表)
长度=0
对于索引,枚举(列表)中的项:
a=项目
对于index2,枚举中的以下内容(列表[索引:):
b=以下
如果已排序([a,b])!=[a,b]:#在这里进行比较,寻找突破模式
如果index2>长度:
长度=index2
开始=索引
打破
a=b#更新当前值以继续
打印(“序列{}长,介于{}和{}之间”。格式(长度、开始、开始+长度-1))
打印(列表[开始:开始+长度])
输出:
[1, 5, 78, 2, 3, 6, 8, 1, 7, 2, 9, 3, 7, 2]
Sequence 4 long, between 3 and 6
[2, 3, 6, 8]
但我确信其中有一个while循环解决方案;) 在线性时间(O(n)时间复杂度)内解决此问题的更有效方法是跟踪当前有序序列的起始索引,以及最长序列的起始索引和结束索引,如果当前有序序列的长度大于先前最长序列的长度,则更新最长序列的起始和结束索引。如果遇到无序项,请将起始索引重置为当前索引:
def find_longest_array(array):
longest_start = longest_end = start = 0
for i, n in enumerate(array):
if i:
if array[i - 1] > n:
start = i
elif i - start > longest_end - longest_start:
longest_start, longest_end = start, i
return longest_start, longest_end
以便:
find_longest_array((2, 1, 2, 3, 2, 1, 5, 2, 4, 5))
返回:
(1, 3)
一种在线性时间内解决此问题的更有效方法(O