分割回文串【JAVA实现】

给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串。

返回 s 所有可能的分割方案。

示例:

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

面对这种需要列出所有可能性的问题,很容易想到的就是使用回溯的方法来解决,分析问题,首先需要把一个复杂的问题分解成相对来说较为简单的子问题,然后将这个子问题的解进行组合就可以找到复杂问题的解了。

举例:

aabb
先考虑在第 1 个位置切割,a | abb
这样我们只需要知道 abb 的所有结果,然后在所有结果的头部把 a 加入
abb 的所有结果就是 [a b b] [a bb]
每个结果头部加入 a,就是 [a a b b] [a a bb]

aabb
再考虑在第 2 个位置切割,aa | bb
这样我们只需要知道 bb 的所有结果,然后在所有结果的头部把 aa 加入
bb 的所有结果就是 [b b] [bb]
每个结果头部加入 aa,就是 [aa b b] [aa bb]

aabb
再考虑在第 3 个位置切割,aab|b
因为 aab 不是回文串,所有直接跳过

aabb
再考虑在第 4 个位置切割,aabb |
因为 aabb 不是回文串,所有直接跳过

最后所有的结果就是所有的加起来
[a a b b] [a a bb] [aa b b] [aa bb]

对这个思路进行编码

class Solution {
    String s;
    List<List<String>> res = new ArrayList<>();
    public List<List<String>> partition(String s) {
        this.s = s;
        List<String> list = new ArrayList<>();
        dfs(list,0);
        return res;
    }
    public void dfs(List<String> list,int index) {
        //已经到了字符串的结尾了,把结果集放到最终解中
        if (index == s.length()) {
            res.add(new ArrayList<>(list));
            return;
        }
        //不断取更长的头串
        for (int i = index;i < s.length();i++) {
            if (isPartition(index,i)) {//判断头串是否是回文
                String temp = s.substring(index,i+1);
                list.add(temp);
                //对后面的字符串进行递归,进行相同的处理
                dfs(list,i+1);
                //删除结尾已有结果,回到上一层(回溯的精髓)
                list.remove(list.size()-1);
            }
        }
    }
    //判断字符串的某一段是否是回文
    public boolean isPartition(int start,int end) {
        while (start < end) {
            if (s.charAt(start) != s.charAt(end)) {
                return false;
            }
            start++;
            end--;
        }
        return true;
    }
}

其实这样是比较直接的解决问题了,这个解法中还有可以优化的地方,就是判断是否是回文的地方,我们会有很多重复的判断。比如已经判断过“aa”是回文了,但是判断“baab”是否是回文的时候还会重复判断,这个地方是可以优化的,我们可以用一个二维空间记录判断过回文的字符串,这样就不用重复的进行判断了。

发布了10 篇原创文章 · 获赞 10 · 访问量 6636

猜你喜欢

转载自blog.csdn.net/zjg379569986/article/details/102505694