0
点赞
收藏
分享

微信扫一扫

Leetcode 131 分割回文串

江南北 07-01 21:00 阅读 3

题目描述

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

示例 1:
输入:s = “aab”
输出:[[“a”,“a”,“b”],[“aa”,“b”]]
示例 2:
输入:s = “a”
输出:[[“a”]]

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

解题思路

字符串的分割方案F(s)是一个可以拆分为子问题的问题,我们设原字符串的长度为n, 考查以当前位置i为起始点的字符串s[i][n], 对应的分割方案结果集为F(s[i][n]),若子字符串s[i][j]是回文串,那么原问题的一个子集可以表示为 {s[i][j] , s[j][n] }.
基于以上思路,我们需要知道字符串 s的所有子字符串的头尾位置,依据这个信息可以加速我们的动态规划过程。
记 s的子字符串的头尾位置i,j是否满足回文串为函数 f[i][j],
f[i][j] = f[i+1][j-1] s.charAt(i) = s.charAt(j)
= false
所以求字符串 s的所有子字符串,这个过程也是一个动态规划,求解 f[i][j] 的时候,为了利用上前置已求得的答案,注意i是递减的, j是递增的

代码实现

import java.util.ArrayList;
import java.util.List;

public class Leetcode131 {

    public static void main(String[] args) {
        String s = "abbab";
        System.out.println(partition(s));
    }

    public static List<List<String>> partition(String s) {
        List<List<String>> r = new ArrayList<>();
        boolean[][] huiwen = new boolean[s.length()][s.length()];
        for (int i = 0; i < s.length(); i++) {
            huiwen[i][i] = true;
        }
        for (int i = s.length() - 1; i >= 0; i--) {
            for (int j = i + 1; j < s.length(); j++) {
                if (s.charAt(i) == s.charAt(j)) {
                    huiwen[i][j] = (j - i == 1) ? true : huiwen[i + 1][j - 1];
                }
            }
        }
        dfs34(s, 0, r, new ArrayList<>(), huiwen);
        return r;
    }

    private static void dfs34(String s, int i, List<List<String>> r, List<String> t, boolean[][] huiwen) {
        if (i == s.length()) {
            r.add(new ArrayList<>(t));
            return;
        }
        for (int j = i; j < s.length(); j++) {
            if (huiwen[i][j] == true) {
                t.add(s.substring(i, j + 1));
                dfs34(s, j + 1, r, t, huiwen);
                t.remove(t.size() - 1); 
            }
        }
    }
}

举报

相关推荐

0 条评论