回溯----7.分割回文串

题目链接

/**

            将字符串分割为若干回文子串;回文子串: 单个字符、正序倒序一样。

            大致执行流程(for循环 + 递归):

                        首先从i = 0开始,从第一个元素处开始切割,判断是否是回文子串

                        若是则保存到tempRes中,并从i + 1处开始重复上述流程从第一个元素开始切割,直到切割到最后一个元素保存结果

                        若不是则迭代i,从下一个元素处开始尝试切割

                        .......

                        回溯:

                            回溯index(起始点),迭代i(切割点),重复上述流程直到切割到最后一个元素

                            继续回溯index,直到最初始的for循环执行完毕切割到最后一个元素,执行完毕得到所有结果          

*/

class Solution {
    //保存所有结果
    private List<List<String>> res = new ArrayList<>();
    //保存单次临时结果
    private List<String> tempResult = new ArrayList<>();

    //避免重复传参
    private String s;

    public List<List<String>> partition(String s) {
        /**
            将字符串分割为若干回文子串;回文子串: 单个字符、正序倒序一样。
            大致执行流程(for循环 + 递归):
                        首先从i = 0开始,从第一个元素处开始切割,判断是否是回文子串
                        若是则保存到tempRes中,并从i + 1处开始重复上述流程从第一个元素开始切割,直到切割到最后一个元素保存结果
                        若不是则迭代i,从下一个元素处开始尝试切割
                        .......
                        回溯:
                            回溯index(起始点),迭代i(切割点),重复上述流程直到切割到最后一个元素
                            继续回溯index,直到最初始的for循环执行完毕切割到最后一个元素,执行完毕得到所有结果           
        */

        this.s = s;
        backtrack(0);

        return res;
    }

    private void backtrack(int index) {
        //回文子串合法性判断在单层搜索逻辑中
        if(index == s.length()) {
            res.add(new ArrayList<>(tempResult));
            return;
        }

        for(int i = index; i < s.length(); i++) {
            //当前切割出的子串是回文子串则保存在temp中,并迭代起点继续切割
            if(isHW(index,i)) {
                tempResult.add(s.substring(index,i + 1)); //substring(start,end)-->[start,end)

                //从i + 1开始继续切割
                backtrack(i + 1);

                //回溯
                tempResult.remove(tempResult.size() - 1);
            }
        }
    }

    //回文子串的判断
    private boolean isHW(int start, int end) {
        while(start < end) {
            if(s.charAt(start) != s.charAt(end)) {
                return false;
            }
            start++;
            end--;
        }
        return true;
    }
}

### Java 分割回文串算法实现 以下是基于回溯法的 `Java` 实现,用于解决分割回文串问题。该方法通过递归遍历所有可能的子串组合,并利用动态规划优化判断回文的过程。 #### 动态规划预处理 为了提高效率,在递归之前先构建一个二维布尔数组 `dp` 来记录字符串中的任意区间 `[i, j]` 是否为回文串。这样可以在后续的递归过程中快速查询某个子串是否满足条件[^1]。 ```java class Solution { boolean[][] dp; List<List<String>> result = new ArrayList<>(); public List<List<String>> partition(String s) { int n = s.length(); dp = new boolean[n][n]; // 预处理 dp 数组 for (int i = n - 1; i >= 0; i--) { for (int j = i; j < n; j++) { if (s.charAt(i) == s.charAt(j) && (j - i <= 2 || dp[i + 1][j - 1])) { dp[i][j] = true; } } } backtrack(s, 0, new ArrayList<>()); return result; } private void backtrack(String s, int start, List<String> currentList) { if (start == s.length()) { result.add(new ArrayList<>(currentList)); return; } for (int end = start; end < s.length(); end++) { if (!dp[start][end]) continue; // 如果当前子串是回文,则加入路径并继续递归 currentList.add(s.substring(start, end + 1)); backtrack(s, end + 1, currentList); // 回溯操作 currentList.remove(currentList.size() - 1); } } } ``` #### 算法说明 1. **初始化 DP 数组** 使用双层循环填充 `dp` 数组,其中 `dp[i][j]` 表示字符串从索引 `i` 到 `j` 的子串是否为回文串。如果两端字符相等且内部部分也是回文(即 `dp[i+1][j-1]==true`),则标记为真[^3]。 2. **回溯函数设计** 定义了一个辅助函数 `backtrack` 进行递归调用。每次尝试将当前位置到某终点之间的子串作为候选者,当确认其为回文时才将其添加至临时列表中,并进一步探索剩余部分[^4]。 3. **终止条件** 当起始位置等于字符串长度时,表示已经完成了一种合法划分方式,此时需保存当前的结果副本[^2]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值