* 动态规划

<?php
/**
 * Created by PhpStorm.
 * User: Mch
 * Date: 8/10/18
 * Time: 00:16
 */
class Solution {
    /**
     * 给定2个字符串$str1, $str2, 返回2个字符串的最长公共子序列
     * $str1 = "1A2C3D4B56", $str2 = "B1D23CA45B6A"
     * "123456"或者"12C4B6"都是最长公共子序列
     * @return int[][]
     */
    private static function getdp(string $str1, string $str2) {
        $n1 = strlen($str1);
        $n2 = strlen($str2);

        $dp = new SplFixedArray($n1);
        for ($i = 0; $i < $dp->getSize(); $i++) {
            $dp->offsetSet($i, new SplFixedArray($n2));
        }
        $dp[0][0] = $str1[0]===$str2[0] ? 1 : 0;
        for ($i = 1; $i < $n1; $i++) {
            $dp[$i][0] = max($dp[$i-1][0], $str1[$i]===$str2[0] ? 1:0);
        }
        for ($j = 1; $j < $n2; $j++) {
            $dp[0][$j] = max($dp[0][$j-1], $str1[0]===$str2[$j]?1:0);
        }
        for ($i = 1; $i < $n1; $i++) {
            for ($j = 1; $j < $n2; $j++) {
                $dp[$i][$j] = max($dp[$i-1][$j], $dp[$i][$j-1]);
                if ($str1[$i]===$str2[$j]) {
                    $dp[$i][$j] = max($dp[$i][$j], $dp[$i-1][$j-1]+1);
                }
            }
        }
        return $dp;
    }

    public static function lcse(string $str1, string $str2) {
        if (is_null($str1) || is_null($str2) || strlen($str1)===0 || strlen($str2)===0) {
            return "";
        }
        $dp = self::getdp($str1, $str2);
        $m = strlen($str1)-1;
        $n = strlen($str2)-1;
        $res = new SplFixedArray($dp[$m][$n]);
        $index = $res->getSize()-1;
        while ($index >= 0) {
            if ($n > 0 && $dp[$m][$n]=== $dp[$m][$n-1]) {
                $n--;
            } else if ($m>0 && $dp[$m][$n]=== $dp[$m-1][$n]) {
                $m--;
            } else {
                $res[$index--] = $str1[$m];
                $m--;
                $n--;
            }
        }
        return array_reduce($res->toArray(), function($carry, $item) {
            $carry .= $item;
            return $carry;
        }, "");
    }
}

$str1 = "1A2C3D4B56";
$str2 = "B1D23CA45B6A";
echo Solution::lcse($str1, $str2).PHP_EOL; // "123456"