每日算法总结——回溯算法、 LeetCode 131. 分割回文串

LeetCode 131. 分割回文串

131. 分割回文串 - 力扣(LeetCode)

什么是回溯算法?

回溯算法真的是解决排列问题的一大利器,其实很多时候自己不经意间就写出了回溯算法,但是一直没有一个系统的认识,今天做一个详细的总结。

概念回溯法(back tracking)(探索与回溯法)是一种选优搜索法,又称为试探法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回到上一步,重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为 “回溯点”。

回溯法和穷举法很像,不如说回溯法是穷举法的一个改进,它在所有可行的选择中,系统地搜索问题的解。它假定解可以由向量形式 ( x 1 , x 2 , . . . , x n ) (x_1,x_2,...,x_n) (x1,x2,...,xn)来表示,其中 x i x_i xi 的值表示在第 i i i 次选择所作的决策值,并以深度优先的方式遍历向量空间,逐步确定 x i x_i xi 的值,直到解被找到。

所以在使用回溯法时,需要在脑中形成一棵解空间构成的树

  • 当我们要解决的问题是要求一个使问题最优的n个元素的子集,问题的解空间常可以组织成一棵子集树
  • 当问题是求n个元素一个排列以使问题最优化时,解空间常可以组织成一棵排列树。

在这里插入图片描述

看到这里会发现,回溯法又和二叉树地深度优先搜索很像,其实具有界限函数的深度优先搜索法又称为回溯法,这里的界限函数又称为剪枝函数

  • 利用剪枝函数,剪除无用的分支,集中搜索最有用的分支,提高搜索效率
  • 其实就是根据已有条件判断还要不要继续向下搜索了,如果当前条件已经不成立了,当然也没有必要继续搜索了。

回溯算法设计步骤

  • 回溯函效
  • 结束条件
  • 结果添加
  • 返回操作
  • 可选选择
  • 剪枝操作
  • 路径添加
  • 下一节点
  • 路径回溯
回到本题

利用回溯算法的思想就很好分析了,可以像切面剂子一样,把字符串一个个切开,每次截取都判断已经切好的部分是否都是回文子串就行了131.分割回文串

class Solution {
    List<List<String>> res;
    public List<List<String>> partition(String s) {
        res = new ArrayList<>();
        if (s.length() == 1) {
            List<String> list = new ArrayList<>();
            list.add(s);
            res.add(list);
            return res;
        }
        List<String> list = new ArrayList<>();
        process(s, 0, list);
        return res;
    }

    public void process(String s, int startIndex, List<String> list) {
        if (startIndex == s.length()) {
            res.add(new ArrayList<>(list));
            return;
        }
        for (int i = startIndex + 1; i <= s.length(); i++) {
            String sub = s.substring(startIndex, i);
            if (!isPalindrome(sub)) {
                continue;
            }
            list.add(sub);
            process(s, i, list);
            list.remove(list.size() - 1);
        }
    }

    /**
     * 判断是否是回文串
     * @param sub 子串
     * @return 是否是回文串
     */
    private boolean isPalindrome(String sub) {
        int left = 0;
        int right = sub.length() - 1;
        while (left < right) {
            if (sub.charAt(left) != sub.charAt(right)) {
                return false;
            }
            left++;
            right--;
        }
        return true;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值