让我们先进行一个简单的实现,然后改进它。
\n\n我们从左向右计算部分和,对于每个位置,我们发现最左边的部分和,例如当前的部分和大于该位置。
\n\ninput a\nint partialSums[len(a)]\nfor i in range(len(a)):\n partialSums[i] = (i == 0 ? 0 : partialSums[i - 1]) + a[i]\n if partialSums[i] > 0:\n answer = max(answer, i + 1)\n else:\n for j in range(i):\n if partialSums[i] - partialSums[j] > 0:\n answer = max(answer, i - j)\n break\nRun Code Online (Sandbox Code Playgroud)\n\n这是 O(n 2 )。现在,找到最左边的“好”总和的部分实际上可以通过BST来维护,其中每个节点将表示为一对(partial sum, index),并通过 进行比较partial sum。此外,每个节点都应该支持一个特殊字段,min该字段是最小的indices。
现在,我们可以使用当前的部分和作为关键字,遵循接下来的三个规则(假设C是当前节点,L并且R分别是左子树和右子树的根),而不是直接搜索适当的部分和:
curMin最初维持在 中找到的“良好”部分和的当前最小索引+\xe2\x88\x9e。C.partial_sum是“好”,则更新curMin为C.index。R然后curMin更新L.min。然后更新answer为i - curMin并将当前的部分和添加到 BST 中。
这将给我们 O(n * log n)。
\n