最多具有K个元素的最大连续子数组
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最多具有K个元素的最大连续子数组相关的知识,希望对你有一定的参考价值。
是否有一种方法可以找到O(N)复杂度最大的连续子数组最多具有K个元素。
或者没有这种可能性。
例如:
A = [4,-2,6,6,4,-2,6]
K = 3
因为中间的6和4等于10,所以该函数应返回10。
P.S。使用O(N * K)很简单,问题是在O(N)中是否可能]
输入:数组X
预处理步骤1
具有相同符号的连续数字加在一起,得到数组Z
。这些和中的每一个都与它表示的X
子序列的第一个索引和最后一个索引(包括该索引)相关联。这些被符号表示为函数start_index
和end_index
;实际的实现将使用数据结构来表示数字及其关联的开始和结束索引。
预处理步骤2
从Z
的开头和结尾除去负数。
计算
max_sum := -infinity
max_range := {.start = naught, .end = naught}
max_range := {.start = start_index(Z[0]), .end = end_index(Z[0])}
sum := Z[0]
for each consecutive pair (neg, pos) in Z[1:]:
new_sum := sum + neg + pos
if new_sum >= sum:
sum := new_sum
else:
sum := pos
max_range := {.start = start_index(pos), .end = end_index(pos)}
if sum > max_sum:
max_sum := sum
max_range := {.start = max_range.start, .end = end_index(pos)}
Z' := reversed(Z)
max_range := {.start = start_index(Z'[0]), .end = end_index(Z'[0])}
sum := Z'[0]
for each consecutive pair (neg, pos) in Z'[1:]:
new_sum := sum + neg + pos
if new_sum >= sum:
sum := new_sum
else:
sum := pos
max_range := {.start = start_index(pos), .end = end_index(pos)}
if sum > max_sum:
max_sum := sum
max_range := {.start = start_index(pos), .end = max_range.end}
输出
X
的最大连续子序列的开始索引和结束索引分别是值max_range.start
和max_range.end
。该子序列的总和是值max_sum
。
复杂度
在预处理步骤1]中,我们迭代输入X
一次,并生成长度为O(n)的输出Z
。总和与相应子序列的开始和结束的关联可以在O(1)时间以及后续查找中完成。 此步骤的时间复杂度为O(n)。
在预处理步骤2]中,我们不需要遍历数组Z
;我们可以简单地更改其开始索引和结束索引(例如Z := Z[1:-1]
)。假设Z
的长度已知并且Z
提供随机访问,则可以在time O(1)
在计算步骤中,我们迭代Z
两次,对每次迭代中的每个元素执行恒定时间的运算。回想一下Z
的长度为O(n),因此此步骤的总复杂度为O(n)
最后,计算后因此,我们获得了结果:
- 最大连续子序列的总和存储在
max_sum
变量中,因此我们可以在恒定时间中访问它” - 子序列的开头和结尾也可以在[[恒定时间中以
max_range.start
和max_range.end
的形式访问]子序列的长度可以在[[恒定时间 中从 - 因此,此算法的总时间复杂度为O(n)。
max_range.start
和max_range.end
中计算。以上是关于最多具有K个元素的最大连续子数组的主要内容,如果未能解决你的问题,请参考以下文章
leetcode每日一题(2021.5.13)——最大子序扣
2022-05-06:给你一个整数数组 arr,请你将该数组分隔为长度最多为 k 的一些(连续)子数组。分隔完成后,每个子数组的中的所有值都会变为该子数组中的最大值。 返回将数组分隔变换后能够得到的元