有n个正数(A1,...An) 在一个圆上,我们如何将这个圆划分为总和大于或等于 m 的子段,以便子段数在 O(n) 或 O(nlogn) 中最大
例如:n = 6 m = 6
31 2 3 6 3
ANS = 3因为我们可以将数组分为三个子段{[2,4],[5,5],[6,1]}
如果数组中至少有一个大于或等于 m
的数字,只需从其中一个数字开始将数组切成尽可能小的片段。否则(如果数字之和至少为2*m
)使用指针追踪算法。
此算法使用 2 个附加数组:L
用于链长度(最初为零),S
用于起始索引(最初等于自己的索引:0、1、2、...)。和 2 个数组索引:F
和 B
(最初为零)。
- 递
- 增
F
而F
和B
之间的总和小于m
。然后在F
和B
之间的总和大于m
时递增B
(但在 is 仍然大于或等于m
时停止)。 - 更新数组:
L[F] = 1 + L[B]
、S[F] = S[B]
。 - 重复步骤 1,2
F<n
。在步骤 1 上递增F
时,将最近更新的值复制到L[F]
和S[F]
。 - 将
F
重置为零。 F
递增,而F
之前和之后的元素之和B
小于m
。然后在F
之前和之后的总和大于B
m
时递增B
(但在 is 仍然大于或等于m
时停止)。- 如果
F <= S[B]
请使用L[B] + 1
更新最大子分段数。 - 重复步骤 5,6,同时
B<n
。