Leetcode 131: 分割回文串

Leetcode 131: 分割回文串

题目描述

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

示例

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

思路

思路1: 回溯+判断

即利用回溯思路不断增加是回文前缀字符串组的后续可能回文串

思路1:代码

class Solution {
    public List> partition(String s) {
        List> result = new LinkedList<>();
        if (s.length() == 0) {
            return result;
        }
        List temp = new LinkedList<>();
        partitionHelper(result, s, 0, temp);
        return result;
    }
    
    private boolean canReverse(String s, int i, int j) {
        if (i >= j) {
            return true;
        }
        if (s.charAt(i++) == s.charAt(j--)) {
            return canReverse(s, i, j);
        } else {
            return false;
        }
    }
    
    private void partitionHelper(List> res, String s, int startIndex, List temp) {
        int size = s.length();
        if (size <= startIndex) {
            res.add(new LinkedList(temp));
            return;
        }
        for(int i = startIndex; i < size; i++) {
            if (canReverse(s, startIndex, i)) {
                temp.add(s.substring(startIndex, i + 1));
                partitionHelper(res, s, i + 1, temp);
                temp.remove(temp.size() - 1);
            }
        }
    }
}

思路2:回溯+动态规划优化

空间换时间,将判断是否是回文看成是一个动态规划,直接使用$n^2$算法求取,之后直接$1$调取

思路2: 代码

public class Solution {
    public List> partition(String s) {
        List> res = new LinkedList>();
        if (s.length() == 0) {
            return res;
        }
        int size = s.length();
        boolean[][] dps = new boolean[size][size];
        for(int right = 0; right < size; right++) {
            for(int left = 0; left <= right; left++) {
                if (s.charAt(left) == s.charAt(right) && (right - left <= 2 || dps[left + 1][right - 1])) {
                    dps[left][right] = true;
                }
            }
        }

        List temp = new LinkedList<>();
        partitionHelper(res, s, 0, temp, dps);
        return res;
    }

    private void partitionHelper(List> res, String s, int startIndex, List temp, boolean[][] dps) {
        int size = s.length();
        if (startIndex >= size) {
            res.add(new LinkedList<>(temp));
            return;
        }
        for(int i = startIndex; i < size; i++) {
            if (dps[startIndex][i]) {
                temp.add(s.substring(startIndex, i + 1));
                partitionHelper(res, s, i + 1, temp, dps);
                temp.remove(temp.size() - 1);
            }
        }
    }
}

复杂度分析

思路1

时间复杂度

$n*2^n?$

空间复杂度

$n*2^n?$

思路2

时间复杂度

$2^n + n^2$

空间复杂度

$n * 2^n + n^2$


文章作者: 小风雷
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 小风雷 !
评论
 上一篇
Leetcode 139: 单词切分 Leetcode 139: 单词切分
Leetcode 139: 单词切分题目描述给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词。 说明:拆分时可以重复使用字典中的单词。 你可以假设字典中没有重
2020-03-19
下一篇 
Leetcode 25:验证回文串 Leetcode 25:验证回文串
Leetcode 25:验证回文串题目描述给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。 说明:本题中,我们将空字符串定义为有效的回文串。 示例示例 1:输入: "A man, a plan, a
2020-03-12
  目录