Leetcode 131、分割回文串 PHP语言

277 阅读1分钟

回溯一直学不会,慢慢来吧。记录一下一些思考过程。争取下次能照葫芦画瓢.

class Solution {

    /**
     * @param String $s
     * @return String[][]
     */
    protected $res = [];
    protected $dp = [];
    function partition($s) {
        $len_s = strlen($s);
        $this->dp = array_fill(0, $len_s, array_fill(0, $len_s, false));
        for ($i = 0; $i < $len_s; $i++) {
            $this->preProcess($s, $i, $i);
            $this->preProcess($s, $i, $i + 1);
        }
        $this->help131($s, 0, $len_s, []);
        return $this->res;
    }
    protected function help131($s, $start, $len_s, $path) {
        if ($len_s === $start) {
            $this->res[] = $path;
            return;
        }

        //aabcdd
        //我们可以依次选择一个前缀字符串,然后一个结果就是
        //比如我们选择字符串 a, 那么一个结果是 a + "abcdd"的结果
        //同样可以继续选择字符串 aa,那么一个结果是 aa + "bcdd"的结果
        for ($i = $start; $i < $len_s; $i++) {
            $pre = substr($s, $start, $i - $start + 1);
            //上面的pre 和下面函数里判断的字符串就是我们所谓的前缀,要是前缀都不是回文的话直接跳过这个选择。
//            if (false === $this->isHuiwen($s, $start, $i)) {
//                continue;
//            }
            if ($this->dp[$start][$i] === false) {
                continue;
            }
            //前缀是回文的话,那么我们继续去下一层找剩余串的结果
            $path[] = $pre;
            //当前位置用过的字符不能继续使用了,这个相当于在剩余的字符串里选择找结果。
            $this->help131($s, $i+1, $len_s, $path);
            //以 a 做前缀的路径处理完了,回溯一下,下次循环准备找以 aa 为前缀的字符串了。
            array_pop($path);
        }
    }

    //中心法扩展
    protected function preProcess($s, $left, $right) {
        $len_s = strlen($s);
        while ($left >= 0 && $right < $len_s && $s[$left] == $s[$right]) {
            $this->dp[$left][$right] = true;
            $left--;
            $right++;
        }
    }

    protected function isHuiwen($s, $i, $j) {
        while ($i < $j) {
            if ($s[$i] === $s[$j]) {
                $i++;
                $j--;
            } else {
                return false;
            }
        }
        return true;
    }
}

这张图比较形象的解释了整个切割的过程。