最大循环子数组和的 PHP 程序
给定 n 个数字(+ve 和 -ve),排列成一个圆圈,找到连续数字的最大和。
例子:
Input: a[] = {8, -8, 9, -9, 10, -11, 12}
Output: 22 (12 + 8 - 8 + 9 - 9 + 10)
Input: a[] = {10, -3, -4, 7, 6, 5, -4, -1}
Output: 23 (7 + 6 + 5 - 4 -1 + 10)
Input: a[] = {-1, 40, -14, 7, 6, 5, -4, -1}
Output: 52 (7 + 6 + 5 - 4 - 1 - 1 + 40)
MApproach:最大和可以有两种情况:
- 情况 1:对最大总和有贡献的元素的排列方式使得没有环绕。示例:{-10, 2, -1, 5}, {-2, 4, -1, 4, -1}。在这种情况下,Kadane 的算法将产生结果。
- 情况 2:对最大总和有贡献的元素被排列成有环绕。示例:{10, -12, 11}, {12, -5, 4, -8, 11}。在这种情况下,我们将包装更改为非包装。让我们看看如何。贡献元素的包装意味着非贡献元素的不包装,因此找出非贡献元素的总和并从总和中减去该总和。要找出非贡献的总和,请反转每个元素的符号,然后运行 Kadane 算法。
我们的数组就像一个环,我们必须消除最大连续负数,这意味着倒置数组中的最大连续正数。最后,我们比较两种情况下得到的和,并返回两个和的最大值。
以下是上述方法的实现。
PHP
$max_kadane)? $max_wrap: $max_kadane;
}
// Standard Kadane's algorithm to
// find maximum subarray sum
// See https://www.geeksforgeeks.org/archives/576 for details
function kadane($a, $n)
{
$max_so_far = 0;
$max_ending_here = 0;
for ($i = 0; $i < $n; $i++)
{
$max_ending_here = $max_ending_here +$a[$i];
if ($max_ending_here < 0)
$max_ending_here = 0;
if ($max_so_far < $max_ending_here)
$max_so_far = $max_ending_here;
}
return $max_so_far;
}
/* Driver code */
$a = array(11, 10, -20, 5, -3, -5, 8, -13, 10);
$n = count($a);
echo "Maximum circular sum is ". maxCircularSum($a, $n);
// This code is contributed by rathbhupendra
?>
输出:
Maximum circular sum is 31
复杂性分析:
- 时间复杂度: O(n),其中 n 是输入数组中的元素数。
因为只需要对数组进行线性遍历。 - 辅助空间: O(1)。
因为不需要额外的空间。
请注意,如果所有数字都是负数,例如 {-1, -2, -3},则上述算法不起作用。在这种情况下它返回 0。这种情况可以通过在运行上述算法之前添加预检查以查看所有数字是否为负来处理。
有关更多详细信息,请参阅有关最大循环子数组和的完整文章!