http://www.imooc.com/article/4313#comment
* Solution.php
<?php
class Solution
{
/**
* dp
* @param $a array
* @return int|mixed
*/
public function maxsub0($a) {
if (empty($a)) {
throw new InvalidArgumentException("error array size");
}
$n = count($a);
$b = new SplFixedArray($n);
$max = $b[0] = $a[0];
for ($i = 1; $i < $n; $i++) {
$b[$i] = $b[$i-1] > 0 ? $b[$i-1] + $a[$i] : $a[$i];
if ($b[$i] > $max) {
$max = $b[$i];
}
}
return $max;
}
/**
* A traditional greedy approach.
* Keep current sum, slide from left to right, when sum < 0, reset sum to 0.
* @param $a
* @return int
*/
public function maxsub1($a) {
if (empty($a)) {
throw new InvalidArgumentException("error array size");
}
$size = count($a);
$sum = 0;
// $max = -(1 << 31);
$max = $a[0];
$cur = 0;
while ($cur < $size) {
$sum += $a[$cur++];
if ($sum > $max) {
$max = $sum;
} else if ($sum < 0) {
$sum = 0;
}
}
return $max;
}
/**
* Divide and conquer
* @param $a array
* @return int
*/
public function maxsub2($a) {
return self::_maxsub($a, 0, count($a)-1);
}
/**
* @param $a
* @param $left
* @param $right
* @return int
*/
private static function _maxsub($a, $left, $right) {
$center = floor($left + ($right - $left) / 2);
// printf("left=%d, center=%d, right=%d\n", $left, $center, $right);
if ($left >= $right) {
return $a[$left] > 0 ? $a[$left] : 0;
}
$leftSum = self::_maxsub($a, $left, $center);
$rightSum = self::_maxsub($a, $center+1, $right);
$sum = 0;
$leftMax = 0;
for ($i = $center; $i >= $left; $i--) {
$sum += $a[$i];
if ($sum > $leftMax) {
$leftMax = $sum;
}
}
$sum = 0;
$rightMax = 0;
for ($i = $center+1; $i <= $right; $i++) {
$sum += $a[$i];
if ($sum > $rightMax) {
$rightMax = $sum;
}
}
$sum = $rightMax + $leftMax;
if ($sum < $leftSum) {
$sum = $leftSum;
}
if ($sum < $rightSum) {
$sum = $rightSum;
}
return $sum;
}
/**
* Spread from max element to both sides
* @param $a array
* @return mixed
*/
public function maxsub3($a) {
$n = count($a);
$k = 0;
for ($i = 1; $i <$n; $i++) {
if ($a[$i] > $a[$k]) {
$k = $i;
}
}
$sum = $max = $a[$k];
$high = $k + 1;
$low = $k - 1;
while ($high <$n) {
$sum += $a[$high];
if ($sum > $max) {
$max = $sum;
}
$high += 1;
}
$sum = $max;
while ($low >= 0) {
$sum += $a[$low];
if ($sum > $max) {
$max = $sum;
}
$low -= 1;
}
return $max;
}
}
* index.php
<?php
/**
* Created by PhpStorm.
* User: mingzhanghui
* Date: 1/16/2020
* Time: 17:41
*/
include "Solution.php";
$a = [-2, 11, -4, 13, -5, -2];
$s = new Solution();
printf("dp: %d\n", $s->maxsub0($a));
printf("greedy: %d\n", $s->maxsub1($a));
printf("divide&conquer: %d\n", $s->maxsub2($a));
printf("spread: %d\n", $s->maxsub3($a));
php index.php
dp: 20
greedy: 20
divide&conquer: 20
spread: 20