最長公共子串問題 Longest Common Substring LCST 動態規劃
阿新 • • 發佈:2018-12-18
* 題目:
給定2個字串$str1, $str2, 返回2個字串的最長公共子串
e.g.
$str1 = "1AB2345CD";
$str2 = "12345EF"
返回: "2345"
要求: 如果$str1 長度為M, $str2長度為N, 實現時間複雜度為O(MxN), 額外空間複雜度為O(1)的方法
* LCST.php
<?php /** * Created by PhpStorm. * User: Mch * Date: 2018/12/1 * Time: 10:29 PM */ class LCST { /** @var string */ private $str1; /** @var string */ private $str2; public function __construct(string $str1, string $str2) { $this->str1 = $str1; $this->str2 = $str2; } private function getdp() : \SplFixedArray { $len1 = strlen($this->str1); $len2 = strlen($this->str2); $dp = new \SplFixedArray($len1); for ($i = 0; $i < $dp->getSize(); $i++) { $dp[$i] = new \SplFixedArray($len2); } for ($i = 0; $i < $len1; $i++) { if ($this->str1[$i] === $this->str2[0]) { $dp[$i][0] = 1; } } for ($j = 1; $j < $len2; $j++) { if ($this->str1[0] === $this->str2[$j]) { $dp[0][$j] = 1; } } for ($i = 1; $i < $len1; $i++) { for ($j = 1; $j < $len2; $j++) { if ($this->str1[$i] === $this->str2[$j]) { $dp[$i][$j] = $dp[$i-1][$j-1] + 1; } } } return $dp; } public function lcst1() : string { $s1 = $this->str1; $s2 = $this->str2; if (is_null($s1) || is_null($s2) || empty($s1) || empty($s2)) { return ""; } $dp = $this->getdp(); $end = 0; $max = 0; $len1 = strlen($s1); $len2 = strlen($s2); for ($i = 0; $i < $len1; $i++) { for ($j = 0; $j < $len2; $j++) { if ($dp[$i][$j] > $max) { $end = $i; $max = $dp[$i][$j]; } } } return substr($s1, $end-$max+1, $max); } public function lcst2() : string { $s1 = $this->str1; $s2 = $this->str2; if (is_null($s1) || is_null($s2) || empty($s1) || empty($s2)) { return ""; } $len1 = strlen($s1); $len2 = strlen($s2); $row = 0; $col = $len2 - 1; $max = 0; $end = 0; while ($row < strlen($s1)) { $i = $row; $j = $col; $len = 0; while ($i < $len1 && $j < $len2) { if ($s1[$i] !== $s2[$j]) { $len = 0; } else { $len++; } if ($len > $max) { $end = $i; $max = $len; } $i++; $j++; } if ($col >0) {$col--;} else {$row++;} } return substr($s1, $end-$max+1, $max); } }
* index.php
<?php /** * Created by PhpStorm. * User: Mch * Date: 2018/12/1 * Time: 10:58 PM */ function __autoload($className) { include $className.'.php'; } $str1 = "1AB2345CD"; $str2 = "12345EF"; $lcst = new LCST($str1, $str2); echo $lcst->lcst1().PHP_EOL; echo $lcst->lcst2().PHP_EOL;