leetcode131_分割回文串

给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串。返回 s 所有可能的分割方案。

示例:

输入: “aab”
输出:
[
[“aa”,“b”],
[“a”,“a”,“b”]
]

1 全局变量: 保存结果
2 参数设计: 递归函数的参数,是将上一次操作的合法状态当作下一次操作的初始位置。这里的参数,我理解为两种参数:状态变量和条件变量。(1)状态变量(state)就是最后结果(result)要保存的值;(2)条件变量就是决定搜索是否完毕或者合法的值。
3 完成条件: 完成条件是决定 状态变量和条件变量 在取什么值时可以判定整个搜索流程结束。搜索流程结束有两种含义: 搜索成功并保存结果 和 搜索失败并返回上一次状态。
4 递归过程: 传递当前状态给下一次递归进行搜索。

res = []    # 定义全局变量保存最终结果
state = []  # 定义状态变量保存当前状态
p,q,r       # 定义条件变量(一般条件变量就是题目直接给的参数)
def back(状态,条件1,条件2,……):
    if # 不满足合法条件(可以说是剪枝,可选)
        return
    if # 状态满足最终要求(可选)
        res.append(state)   # 加入结果,必须有
        return 
    # 主要递归过程,一般是带有 循环体 或者 条件体
    for # 满足执行条件
    	if  # 满足执行条件
       		back(状态,条件1,条件2,……)
back(状态,条件1,条件2,……)
return res

由于要求给出具体路径,这里考虑回溯法
这种题目其实有一个通用的解法,模板:
1, 以当前位置为源流往下摸排所有可以跳到的位置
2, 最终递归返回源流位置
3, 然后再以下面一个位置作为源流位置,重复上述操作

全局变量:该题目要找到可分割的方案,最终结果形式上是:[[],[],[],…]
参数设计:(1)状态变量:当前是回文的字符串(2)条件变量:剩余待搜索的字符串,当字符串长度为0,则搜索完毕。
完成条件:剩余字符串长度为0。
递归过程:在剩余字符串中遍历,如果该串为回文 就 进入下次递归,如果非回文 就 继续搜索下一个串。

class Solution:
    def partition(self, s: str):
        res = []    # 定义全局变量保存最终结果
        state = []  # 定义状态变量保存当前状态
        n = len(s)

        # dp = [[0]*n for _ in range(n)]
        # for i in range(n-1, -1, -1):
        #    dp[i][i] = 1
        #    for j in range(i+1, n):
        #        if (s[j] == s[i]) and (j-i<=2):
        #            dp[i][j] = 1 
        #        elif (s[j] == s[i]) and (dp[i+1][j-1]):
        #            dp[i][j] = 1

        def back(res,state,index):
            # 分割问题都需要用到所有元素,要体现到完成条件里面
            if index == n:
                res.append(state.copy())
                return
            for i in range(index,n):
                # 当i=index的时候,s[index:i+1]=s[index]
                # 一个字符就是一个回文串,所以也要添加到状态
                # if s[index:i+1] == s[index:i+1][::-1]:
                if dp[index][i]:
                    # 分割问题由于需要用到所有元素,因此用[:xxx]来切片
                    state = state + [s[index:i+1]]
                    back(res,state,i+1)
                    state.pop()
        back(res,state,0)
        return res

对比leetcode 93 复原ip地址
有效 IP 地址 正好由四个整数(每个整数位于 0 到 255 之间组成,且不能含有前导 0),整数之间用 ‘.’ 分隔。

例如:“0.1.2.201” 和 “192.168.1.1” 是 有效 IP 地址,但是 “0.011.255.245”、“192.168.1.312” 和 “192.168@1.1” 是 无效 IP 地址。
给定一个只包含数字的字符串 s ,用以表示一个 IP 地址,返回所有可能的有效 IP 地址,这些地址可以通过在 s 中插入 ‘.’ 来形成。你 不能 重新排序或删除 s 中的任何数字。你可以按 任何 顺序返回答案。

示例 1:

输入:s = “25525511135”
输出:[“255.255.11.135”,“255.255.111.35”]
示例 2:

输入:s = “0000”
输出:[“0.0.0.0”]
示例 3:

输入:s = “101023”
输出:[“1.0.10.23”,“1.0.102.3”,“10.1.0.23”,“10.10.2.3”,“101.0.2.3”]

同样是分割问题

class Solution:
    def restoreIpAddresses(self, s: str):
        res = []  # 定义全局变量保存最终结果
        state = []  # 定义状态变量保存当前状态
        n = len(s)

        def back(res, state, q):
        	# 分割问题都需要用到所有元素,要体现到完成条件里面
            if (q == n) and (len(state) == 4):
                res.append(".".join(state))
                return
            # 如果没有用到所有元素但是又无法再进行下去,说明这次摸牌失败
            # 应该返回nothing
            elif (q == n) or (len(state) == 4):
                return

            # q为ip地址其中一段的起始位,而每一段最多3位,因此可以简化遍历
            for i in range(q, min(q + 3, n)): 
                # 如果一段的第一位是0,则继续扩大是失效的,需要break
                if int(s[q]) == 0:
                    state = state + [s[q]]
                    back(res, state, q + 1)
                    state.pop()
                    break
                elif 0 <= int(s[q:i+1]) <= 255:
                    # 分割问题由于需要用到所有元素,因此用[:xxx]来切片
                    state = state + [s[q:i+1]]
                    back(res, state, i + 1)
                    state.pop()

        back(res, state, 0)
        return res
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值