<span>【题解】力扣 131. 分割回文串</span>

题目来源

131. 分割回文串

思路

方法一

dfs

以截取的字符子串是否符合条件,是否是回文串,来判断是否构成一条分支。

如果是回文串,就将这一子串添加到路径中,并开始下一轮搜索。

如果搜索的下标等于字符串长度,就代表搜索完了,将路径添加到答案中。

可以根据树形结构来理解dfs中的for循环

本题的树形结构是一颗多叉树,树形结构如下:

class Solution {
    public List<List<String>> partition(String s) {
        char[] ch = s.toCharArray();
        int len = ch.length;
        List<List<String>> res = new ArrayList();
        Deque<String> path = new ArrayDeque();
        dfs(ch, 0, len, path, res);
        return res;
    }

    public void dfs(char[] ch, int index, int len, Deque<String> path, List<List<String>> res){
        // 搜索完毕,添加到答案中并返回
        if(index == len){
            res.add(new ArrayList(path));	// new一个ArrayList,相当于复制一个path
            return;
        }
        
        // 从下标开始,截取1个、2个、3个、...直到截取下标到字符串最后一个字母为止。
        for(int i = index;i<len;i++){
            
            // 判断是不是回文串,如果不是,就剪枝
            if(!check(ch, index, i)){
                continue;
            }
            // 直接截取字符串会消耗性能,String.substring(String str, int start, int end),[start,end-1]。
            // 所以用构造方法代替 new String(char[] ch, int index, int len); 从index开始构造长度为len的字符串
            path.addLast(new String(ch, index, i+1-index));
            dfs(ch, i+1, len, path, res);
            path.removeLast();	// 回溯
        }
    }

    // 判断回文串
    public boolean check(char[] ch, int left, int right){
        while(left < right){
            if(ch[left] != ch[right]){
                return false;
            }
            left++;
            right--;
        }
        return true;
    }

}

方法二

动态规划+dfs

在方法一中,我们在check方法里面输出每次检查的left指针和right指针,

public boolean check(char[] ch, int left, int right){
    System.out.printf("%d %d\n",left, right);
    while(left < right){
        if(ch[left] != ch[right]){
            return false;
        }
        left++;
        right--;
    }
    return true;
}
/*
以s="aab"为例:
0 0
1 1
2 2
1 2
0 1
2 2(重复)
0 2
*/

会出现重复检查子串是不是回文串的情况,为了避免重复检查,我们使用动态规划来解决这个问题。

我们可以将所有的子串是否是回文,先提前用二维数组存起来。

定义dp子问题:dp[i][j]:从i到j的子串是否为回文。

dp[i][j]为真的情况:

  1. i==j时,子串只有一个字符,肯定是回文
  2. j-1==i时,子串由两个字符组成,字符必须相同s[i] == s[j]
  3. j-1>i时,子串由两个以上的字符组成,s[i] == s[j],且dp[i+1][j-1] == true 即除去首尾字符的剩余子串也是回文子串

对于1、2、时base case,如下图地蓝色和粉色格子,不需要递推出来,第3点时状态转移方程。我们需要合适的扫描方向,才不会出现:求当前dp[i][j]时,它所以来的dp[i+1][j-1]还没求出来

class Solution {

    char[] ch;
    boolean[][] dp;
    List<List<String>> res;
    Deque<String> path;

    public List<List<String>> partition(String s) {
        ch = s.toCharArray();
        int len = ch.length;
        
        // 预处理
        // 对所有有可能截取的字符串,判断它们是否构成回文串
        dp = new boolean[len][len];
        for(int right = 0;right<len;right++){
            for(int left = 0;left<=right;left++){	// 这里left<=right的情况,相当于上文所说的第一点
                if(left == right){
                    dp[left][right] = true;
                }else if(right - left == 1 && ch[left] == ch[right]){
                    dp[left][right] = true;
                }else if(right - left > 1 && ch[left] == ch[right] && dp[left+1][right-1]){
                    dp[left][right] = true;
                }else{
                    dp[left][right] = false;
                }
            }
        }
        res = new ArrayList();
        path = new ArrayDeque();
        dfs(0, len);
        return res;
    }

    public void dfs(int index, int len){
        if(index == len){
            res.add(new ArrayList(path));
            return;
        }
        for(int i = index;i<len;i++){
            if(dp[index][i]){
                path.addLast(new String(ch, index, i+1-index));
                dfs(i+1, len);
                path.removeLast();
            }
        }
    }
}

参考来源

  1. liweiwei1419
  2. 笨猪爆破组
全部评论

相关推荐

行云流水1971:这份实习简历的优化建议: 结构清晰化:拆分 “校园经历”“实习经历” 板块(当前内容混杂),按 “实习→校园→技能” 逻辑排版,求职意向明确为具体岗位(如 “市场 / 运营实习生”)。 经历具象化:现有描述偏流程,需补充 “动作 + 数据”,比如校园活动 “负责宣传” 可加 “运营公众号发布 5 篇推文,阅读量超 2000+,带动 300 + 人参与”;实习内容补充 “协助完成 XX 任务,效率提升 X%”。 岗位匹配度:锚定目标岗位能力,比如申请运营岗,突出 “内容编辑、活动执行” 相关动作;申请市场岗,强化 “资源对接、数据统计” 细节。 信息精简:删减冗余表述(如重复的 “负责”),用短句分点,比如 “策划校园招聘会:联系 10 + 企业,组织 200 + 学生参与,到场率达 85%”。 技能落地:将 “Office、PS” 绑定经历,比如 “用 Excel 整理活动数据,输出 3 份分析表;用 PS 设计 2 张活动海报”,避免技能单独罗列。 优化后需强化 “经历 - 能力 - 岗位需求” 的关联,让实习 / 校园经历的价值更直观。 若需要进一步优化服务,私信
实习,投递多份简历没人回...
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务