圆阵列

时间:2016-03-11 12:11:02

标签: arrays algorithm segments

圆上有n个正数(A1,... An),我们如何将这个圆划分为大于或等于m的子段,以便O(n)或O中的子段数最大(nlogn)

例如: n = 6 m = 6

3 1 2 3 6 3

ANS = 3 因为我们可以将数组分成三个子段{[2,4],[5,5],[6,1]}

1 个答案:

答案 0 :(得分:2)

如果数组中至少有一个数字大于或等于m,只需从这些数字中的一个开始将数组切割成最小的可能部分。否则(如果数字的总和至少为2*m),则使用指针追逐算法。

该算法使用2个额外的数组:L用于链长(最初为零)和S用于起始索引(最初等于自己的索引:0,1,2,...)。 2个数组索引:FB(最初为零)。

  1. FF之间的总和小于B时增加m。然后递增B,而FB之间的总和大于m(但是当仍然大于或等于m时停止。)
  2. 更新数组:L[F] = 1 + L[B]S[F] = S[B]
  3. F<n时重复步骤1,2。在第1步增加F时,将最近更新的值复制到L[F]S[F]
  4. F重置为零。
  5. 增加F,而F之前和B之后的元素总和小于m。然后在B之前和F之后的总和增加B时增加m(但是当仍然大于或等于m时停止)。
  6. 如果F <= S[B]使用L[B] + 1更新最大子分段数。
  7. B<n
  8. 时重复步骤5,6