简单的方法是在 O(N^2) 时间内完成。但是,您可以花费空间来完成 O(N log N) 时间。该解决方案并不完全遵循 geeksforgeeks,但会为您提供 O(N Log N) 解决方案。我附上了图片以便更好地理解。
让我们获取一个输入数组 (-2, 3,1,-2,1,1) 并创建前缀和数组。
前缀和数组是直到当前元素的所有元素的总和:[-2, 1, 2, 0, 1, 2]
例如:在输入数组的索引 2 处,之前和包括它的所有元素的总和:-2+3+1=2
请注意:在下面的方法中,前缀子数组和数组表示相同的东西。对于原始输入数组,我将其称为原始数组。
- 您创建一个前缀和数组并存储用于创建此前缀和数组 (0-5) 的索引并将其放入队列中。
- 从队列中取出第一个内容(前缀和数组)。现在,如果您在前缀和数组中的最后一个值大于或等于 K,那么您用于创建此数组的索引就是答案。
- 如果不是,那么让我们将此前缀数组分解为两个子前缀和数组,并将它们都添加到队列中。也存储他们的索引。
- 一个由从前缀和数组的开始到结束-1 的子前缀数组组成。 - 第二部分(略有变化)由从 start+1 到 end 的前缀和数组组成。在第二部分中,您必须从子数组中存在的每个元素中减去第一个元素(如果您检查附加的图像,它将变得非常明显)。
返回第 2 步并重复,直到队列为空或找到解决方案。
进一步优化:您可以使用 memoization 来减少分支。如果您已经处理了前缀子数组和,则无需再次重新评估它。
下图是将输入转换为前缀数组和,并反复分解为前缀子数组和,直到我们的前缀子数组和的最后一个元素>=k
注意:每个节点由 key 组成:我们正在考虑的前缀子数组的索引。 value = 实际前缀数组总和
希望图表会更清楚。
- 假设您的 k=3 和输入数组 =(-2, 3,1,-2,1,1)
- 您创建前缀和数组 =[{0-5=[-2, 1, 2, 0, 1, 2]}]
- 由于前缀和数组中的最后一个元素
- 0-4 的子数组=> [-2, 1, 2, 0, 1]
- 1-5 的子数组=> [1, 2, 0, 1, 2](每个元素减去-2)得到[3, 4, 2, 3, 4] 一个合适的前缀子数组
- 现在您在前缀子数组总和中的最后一个元素是 4(大于 K),您给出的答案是此类子数组的索引是 1-5