题意:

image.png

解题思路:

  1. 思路:
  2. 动态规划可以理解为:用一个数来表示一个集合,属性里求的最小值,dp[i]表示:将字符串从最左边到第i位分割成回文串,最小的分割次数;
  3. 1. k看成一个分界点,左边dp[k-1]的意思是从1~k-1分割成回文串的最小次数,
  4. 2. 右边a[k~i]如果是一个回文串,则dp[i] = 左边回文串的最小分割次数 + 1,也就是dp[k - 1] + 1

PHP代码实现:

  1. class Solution {
  2. /**
  3. * @param String $s
  4. * @return Integer
  5. */
  6. function minCut($s) {
  7. $n = strlen($s);
  8. $s = ' '. $s;
  9. $g = array_fill(0, $n + 1, array_fill(0, $n + 1, 0));
  10. $f = array_fill(0, $n + 1, PHP_INT_MAX);
  11. for ($j = 1; $j <= $n; $j++) {
  12. for ($i = 1; $i <= $n; $i++) {
  13. if ($i == $j) $g[$i][$j] = true;
  14. else if ($s[$i] == $s[$j]) {
  15. if ($i + 1 > $j - 1 || $g[$i + 1][$j - 1]) $g[$i][$j] = true;
  16. }
  17. }
  18. }
  19. $f[0] = 0;
  20. for ($i = 1; $i <= $n; $i++) {
  21. for ($j = 1; $j <= $i; $j++) {
  22. if ($g[$j][$i]) {
  23. $f[$i] = min($f[$i], $f[$j - 1] + 1);
  24. }
  25. }
  26. }
  27. return $f[$n] - 1;
  28. }
  29. function minCut1($s) {
  30. $len = strlen($s);
  31. for ($i = 0; $i < $len; $i++) $dp[$i] = $i;
  32. for ($i = 0; $i < $len; $i++) {
  33. $this->update($dp, $s, $i, $i, $len);
  34. $this->update($dp, $s, $i, $i + 1, $len);
  35. }
  36. return $dp[$len - 1];
  37. }
  38. function update(&$dp, $s, $left, $right, $len) {
  39. while ($left >= 0 && $right < $len && $s[$left] == $s[$right]) {
  40. if ($left == 0) $dp[$right] = 0;
  41. else $dp[$right] = min($dp[$right], $dp[$left - 1] + 1);
  42. $left--;
  43. $right++;
  44. }
  45. }
  46. }