leetcode 131@月落乌啼oez

本文深入探讨使用回溯算法解决字符串分割为回文子串的问题,通过详细代码示例,讲解了如何判断回文串,递归实现分割方案,并附有Python及Java代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述
给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串。
返回 s 所有可能的分割方案。
示例:
输入: “aab”
输出:
[
[“aa”,“b”],
[“a”,“a”,“b”]
]
解决思路
  这个题一看就是使用回溯算法,但是看见回溯就脑袋疼,可能是还没有转过弯来。最后看了一下别人的思路,还是三要素啊三要素,终止条件,条件(啥时候继续进行)以及选择(这一步干啥)。
  递归的时候其实就是把问题当成一个只有2步或者3步的事,以小见大。回溯是每一个子答案结束之后,能够回到子答案生成之前的状态。
  这个题的思路是这样的,先放进去第一个字符,是不是满足条件?如果满足,前进,再放第二个,以此类推,如果一直满足,则把答案记录在册。不满足则退出。
  条件就是是不是回文字符串了,终止条件就是可以方入的字符串为空或者说长度为0。选择指的是放入几个?
  这个东西不能钻进去妄图追踪计算机一步一步的细节,否则得不偿失,刚刚又妄图追踪,结果又把自己绕晕了。
  代码如下,这次用python写的,一会用java写一遍。

class Solution:
    def partition(self, s):
        """
        :type s: str
        :rtype: List[List[str]]
        """
        res = []
        sub_res = []
        self.helper(res,s,sub_res)
        return res
    
    def helper(self,res,s,sub_res):
        if(len(s)==0):
            res.append(sub_res[:])(2)
        for i in range(1,len(s)+1):
            if self.isPalindrome(s[:i]):
                sub_res.append(s[:i])
                self.helper(res,s[i:],sub_res)
                sub_res.pop() #(1)
    def isPalindrome(self,s):
        if(len(s)==0):
            return False
        i =0
        j=len(s)-1
        while(i<=j):
            if s[i] != s[j]:
                return False
            i+=1
            j-=1
        return True

(1)处就是这个题中的回溯了,其实可以用sub_res+[s[:i]]的写法,但是自我感觉不如使用上面的写法表达的回溯更加清晰,sub_res+[s[:i]]的回溯是隐式的。(小白,写的不对的地方,还请大佬指教。)

  在(2)处不要直接使用sub_res本身,因为python里面除了基本类型其他的都是引用,也可以使用copy函数。


java代码(好坑啊,把<=写成了<,导致调了半天。要注意,结束条件是字符串为空或者说字符长度为0的时候,也就是s.sunstring(s.length(),s.length())的时候才会满足终止条件,如果i到达不了s.length(),那就永远不会满足终止条件,自然答案不会被添加了。

class Solution
{
	

	public List<List<String>> partition(String s)
	{

		List<List<String>> ans = new ArrayList<>();
		List<String> sub_ans = new ArrayList<>();
		help(ans, sub_ans, s);
		return ans;
	}

	private void help(List<List<String>> ans, List<String> sub_ans, String s)
	{
		System.out.println("S.LENGTH:"+s.length());
		if (s.length() == 0) {
			ans.add(new ArrayList<String>(sub_ans));
			System.out.println(11111);
		}
			
		for (int i = 0; i <= s.length(); i++)
		{
			if (check(s.substring(0, i)))
			{
				sub_ans.add(s.substring(0, i));
				help(ans, sub_ans, s.substring(i, s.length()));
				sub_ans.remove(sub_ans.size() - 1);
			}
		}
	}

	private boolean check(String s)
	{
		if(s.length()==0)
			return false;
		int i = 0;
		int j = s.length() - 1;
		while (i <= j)
		{
			if (s.charAt(i) != s.charAt(j))
				return false;
			i++;
			j--;
		}
		return true;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值