剑指Offer || 086.分割回文串

题目

给定一个字符串 s ,请将 s 分割成一些子串,使每个子串都是 回文串 ,返回 s 所有可能的分割方案。

回文串 是正着读和反着读都一样的字符串。

示例 1:

输入:s = "google"
输出:[["g","o","o","g","l","e"],["g","oo","g","l","e"],["goog","l","e"]]

示例 2:

输入:s = "aab"
输出:[["a","a","b"],["aa","b"]]

示例 3:

输入:s = "a"
输出:[["a"]]

提示:

  • 1 <= s.length <= 16
  • s 仅由小写英文字母组成

注意:本题与主站 131 题相同: 力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

LCR 086. 分割回文串 - 力扣(LeetCode)

题解

回溯,从i到j看是不是回文,j到达n后加入到result里。然后i从j+1继续往下走看,最后退出dfs时要将当前ans的最后一个元素去掉。判断回文可以使用dp。f[i][j]={true  if i>=j;(s.charAt(i)==s.charAt(j))&&f[i+1][j-1]},构造完成之后,查询i到j是否回文只需要O(1)时间复杂度

代码:

class Solution {
    boolean[][] f;
    List> tmp = new ArrayList>();
    List ans = new ArrayList();
    int n;
    public String[][] partition(String s) {
        n = s.length();
        f = new boolean[n][n];
        for (int i = 0; i < n; ++i) 
            Arrays.fill(f[i], true);
        //dp判断[i,j]是否回文
        for (int i = n - 1; i >= 0; --i) {
            for (int j = i + 1; j < n; ++j) 
                f[i][j] = (s.charAt(i) == s.charAt(j)) && f[i + 1][j - 1];
        }
        dfs(s, 0);
        int rows = tmp.size();
        String[][] ret = new String[rows][];
        for (int i = 0; i < rows; ++i) {
            int cols = tmp.get(i).size();
            ret[i] = new String[cols];
            for (int j = 0; j < cols; ++j) 
                ret[i][j] = tmp.get(i).get(j);
        }
        return ret;
    }
    public void dfs(String s, int i) {
        if (i == n) {
            tmp.add(new ArrayList(ans));
            return;
        }
        for (int j = i; j < n; ++j) {
            if (f[i][j]) {
                ans.add(s.substring(i, j + 1));
                dfs(s, j + 1);
                ans.remove(ans.size() - 1);
            }
        }
    }
}

你可能感兴趣的:(leetcode刷题,算法)