力扣(LeetCode)-131 分割字符串

本题考察的是深度优先搜索+回溯+回文串判断

题目描述

给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串。
返回 s 所有可能的分割方案。
示例:
输入: “aab”
输出:
[
[“aa”,”b”],
[“a”,”a”,”b”]
]

题目思考+算法分析

1.本题需要将所有的分割方法都找出来,所以肯定需要用到DFS(深度优先搜索)或者BFS(广度优先搜索)
2.每一个字符串都可以分为两部分:左边一个回文串加右边一个子串,比如”abc”可分为”a”+”bc”。然后对”bc”分割仍然是同样的方法,分为”b”+”c”。
3.优先寻找更短的回文串,然后回溯找稍微长一些的回文串分割方法,不断回溯,分割,直到找到所有的分割方法。
比如,分割”aac”,
(1)分割为 a + ac
(2)分割为 a + a+ c,分割完成,得到一组结果,回溯到a+ ac
(3)a+ ac中ac不是回文串,继续回溯,回溯到 aac
(4)分割为稍长的回文串,分割为 aa+c 分割完成得到一组结果,回溯到aac
(5)aac不会回文串,搜索完成

所以,本题的解法就是深度优先搜索+回文串判断+回溯

代码

java 7ms 85%

class Solution {
    List<List<String>> res = new ArrayList<>();
    
    public List<List<String>> partition(String s) {
        if(s==null||s.length()==0)
            return res;
        DFS_ReCall(s,new ArrayList<String>(),0);
        return res;
    }
    /**
    * 深度优先搜索(优先搜索长度短的回文串)+回溯(搜索所有长度的回文串)
    */
    public void DFS_ReCall(String s,List<String> remain,int left){
        if(left==s.length()){  //判断终止条件
            res.add(new ArrayList<String>(remain));  //添加到结果中
            return;
        }
        for(int right=left;right<s.length();right++){  //从left开始,依次判断left->right是不是回文串
            if(isPalindroom(s,left,right)){  //判断是否是回文串
                remain.add(s.substring(left,right+1));   //添加到当前回文串到list中
                DFS_ReCall(s,remain,right+1);  //从right+1开始继续递归,寻找回文串
                remain.remove(remain.size()-1);  //回溯,从而寻找更长的回文串
            }
        }
    }
    /**
    * 判断字符串s的子串(left->right)是否是回文串
    */
    public boolean isPalindroom(String s,int left,int right){
        while(left<right&&s.charAt(left)==s.charAt(right)){
            left++;
            right--;
        }
        return left>=right;
    }
}
    原文作者:小怪兽LY
    原文地址: https://www.jianshu.com/p/23bc70f45331
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞