Given a string s, partition s such that every substring of the partition is a palindrome.
Return the minimum cuts needed for a palindrome partitioning of s.
For example, given s ="aab",
Return 1 since the palindrome partitioning ["aa","b"] could be produced using 1 cut.
分割字符串s,使得每个子字符串都是一个回文串。返回满足条件分割方法的最小次数。
例如:字符串aab,返回1就行,分割一次为aa和b,就满足要求。
思路:
首先需要知道从第几个字符到第几个字符是回文串,然后再获取最小的分割次数。
例如:i-j是一个回文串,那么0-j的分割次数就是arrRet[i]+1。
那么该动态规划模型为:
(1)正向动态规划
当i-j是一个回文串,那么0-j的分割次数就可以是arrRet[i-1]+1
当i-j不是一个回文串,那么0-j的分割次数就可以是arrRet[j-1]+1
所以0-j的分割次数就
arrRet[j]=min(arrRet[i-1]+1,arrRet[j-1]+1);
最终结果为arrRet[最后]
(2)反向动态规划
当i-j是一个回文串,那么i-最后的分割次数就可以是arrRet[j+1]+1
当i-j不是一个回文串,那么i-最后的分割次数就可以是arrRet[i+1]+1
所以0-j的分割次数就
arrRet[i]=min(arrRet[j+1]+1,arrRet[i+1]+1);
最终结果为arrRet[0]
<?php
//反向动态规划
function minCut($s) {
$s = strval($s);
$len = strlen($s);
if ($len < 2) {
return 0;
}
$arrIsPal = array();
$arrRet = array();
//获取从i-j是否是回文串
for ($i = 0; $i < $len; $i ++) {
for ($j = $i; $j < $len; $j ++) {
$subStr = substr($s, $i, $j - $i + 1);
$revSubStr = strrev($subStr);
if ($subStr === $revSubStr && $i != $j) {
$arrIsPal[$i][$j] = 1;
} else {
$arrIsPal[$i][$j] = 0;
}
}
}
print json_encode($arrIsPal)."\n";
//搭建动态规划,获取最小分割次数
for ($i = $len - 1; $i >= 0; $i --) {
$tmp = $len - 1 - $i;
for ($j = $i ; $j < $len; $j ++) {
//如果i-j是回文串
if ($arrIsPal[$i][$j]) {
if ($j == $len - 1) {
$tmp = 0;
} else {
$tmp = $arrRet[$j + 1] + 1;
}
}
}
$arrRet[$i] = min($tmp, $arrRet[$i + 1] + 1);
}
print json_encode($arrRet)."\n";
return $arrRet[0];
}
$str = 'abb';
$ret = minCut($str);
print $ret;
<?php
//正向动态规划
function minCut($s) {
$s = strval($s);
$len = strlen($s);
if ($len < 2) {
return 0;
}
$arrIsPal = array();
$arrRet = array();
//获取从i-j是否是回文串
for ($i = 0; $i < $len; $i ++) {
for ($j = $i; $j < $len; $j ++) {
$subStr = substr($s, $i, $j - $i + 1);
$revSubStr = strrev($subStr);
if ($subStr === $revSubStr && $i != $j) {
$arrIsPal[$i][$j] = 1;
} else {
$arrIsPal[$i][$j] = 0;
}
}
}
print json_encode($arrIsPal)."\n";
//搭建动态规划,获取最小分割次数
for ($i = 0; $i < $len; $i ++) {
$tmp = $i - 0;
for ($j = $i ; $j >= 0; $j --) {
//如果i-j是回文串
if ($arrIsPal[$j][$i]) {
if ($j == 0) {
$tmp = 0;
} else {
$tmp = $arrRet[$j - 1] + 1;
}
}
}
$arrRet[$i] = min($tmp, $arrRet[$i - 1] + 1);
}
print json_encode($arrRet)."\n";
return $arrRet[$len - 1];
}
$str = 'abb';
$ret = minCut($str);
print $ret;