131.分割回文串

本文介绍了一种使用回溯算法解决LeetCode 131题——分割回文串的方法。通过横向和纵向遍历,结合双指针判断回文数的技术,实现了所有可能的分割方案。

https://leetcode.cn/problems/palindrome-partitioning/

思路:

先思考暴力算法能否可行?
很明显是不行的,以aab为例,需要一个一个遍历
首先需要遍历aab,例如先遍历到a,判断a是回文数,然后剩下ab
需要对ab进行遍历、判断a或者ab是否是回文数
首先判断ab不是,然后a|a|是回文数
之后还需要对剩下的b进行判断,判断b是否是回文数
相当于需要3层遍历,所以得使用回溯算法
image.png

回溯思路:
1、首先是横线切割,使用for进行遍历即可,相当于第一层,对a,a,b一个一个进行切割
2、纵向遍历,使用的是递归,记住递归的方式,相当于自己调自己,然后切割从下一个开始,以先切割a为方式,相当于需要对ab进行切割
3、确认什么是回文数?如果是回文数,且切割到最后一个数据的时候,则可以将数据放入结果了

使用队列进行数据的短暂存放 Deque

/**
    * 131. 分割回文串
    */

//用于存放最终结果
    private List<List<String>> res131=new ArrayList<>();
//队列 存放遍历的数据
    private Deque<String> path131=new ArrayDeque<>();


    public List<List<String>> q131(String s) {
        bt131(s,0);
        return res131;
    }


//
    private void bt131(String s,Integer index){
        //如果切割的下标>=数组的长度的时候,则证明是最后一个数据
        //就可以将起加入数组中了
        if(index>=s.length()){
            res131.add(new ArrayList<>(path131));
            return;
        }


        //横向遍历
        for (int i = index; i <s.length() ; i++) {
            if(isHuiwen(s,index,i)){
                path131.addLast(s.substring(index,i+1));
            }else{
                continue;
            }
            
            //纵向遍历,对当前i之后的数据进行切割
            bt131(s,i+1);
            //需要将队列中的最后一个移除
            path131.removeLast();
        }
    }

    //回文数:双指针
    private boolean isHuiwen(String s, Integer start, Integer end){
        for (int i = start,j=end; i < j ; i++,j--) {
           if(s.charAt(i)!=s.charAt(j)) {
               return false;
           }
        }
        return true;
    }

写的还不是很好,需要继续学习如何更好的表述!

好的,这是一个有趣的问题,使用 Kotlin 可以很方便地解决。 我的思路是使用回溯法,遍历所有可能的分割方式,并判断每个子串是否为回文串。 具体实现细节如下: 首先定义一个函数 `isPalindrome` 用于判断一个字符串是否为回文串,这个函数的实现非常简单,只需要判断字符串正着读和反着读是否相等即可。 ```kotlin fun isPalindrome(str: String): Boolean { return str == str.reversed() } ``` 接下来定义一个函数 `partition` 用于遍历所有可能的分割方式。这个函数的参数包括原始字符串 `s`,当前处理到的位置 `start`,当前已经分割出来的子串列表 `cur`,以及最终的结果列表 `res`。 在这个函数中,我们首先判断当前位置是否已经到达字符串末尾。如果是,就把当前的分割方案添加到结果列表中。否则,我们从当前位置开始往后遍历,尝试分割出一个回文子串。如果找到了一个回文子串,我们就把它添加到子串列表中,然后递归处理后面的子串。最后,记得要回溯到上一个状态,把添加的子串从列表中移除。 ```kotlin fun partition(s: String, start: Int, cur: MutableList<String>, res: MutableList<List<String>>) { if (start == s.length) { res.add(cur.toList()) return } for (i in start until s.length) { val str = s.substring(start, i + 1) if (isPalindrome(str)) { cur.add(str) partition(s, i + 1, cur, res) cur.removeAt(cur.lastIndex) } } } ``` 最后,我们可以在主函数中调用 `partition` 函数,并返回结果列表。完整代码如下: ```kotlin fun isPalindrome(str: String): Boolean { return str == str.reversed() } fun partition(s: String, start: Int, cur: MutableList<String>, res: MutableList<List<String>>) { if (start == s.length) { res.add(cur.toList()) return } for (i in start until s.length) { val str = s.substring(start, i + 1) if (isPalindrome(str)) { cur.add(str) partition(s, i + 1, cur, res) cur.removeAt(cur.lastIndex) } } } fun partition(s: String): List<List<String>> { val res = mutableListOf<List<String>>() partition(s, 0, mutableListOf(), res) return res } ``` 你可以使用以下代码测试这个函数: ```kotlin fun main() { val s = "aab" val res = partition(s) println(res) } ``` 输出结果为: ``` [[a, a, b], [aa, b]] ``` 这说明我们的代码已经正确地找到了字符串所有可能的回文子串分割方式。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WalkerShen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值