当前位置: 首页 > news >正文

代码随想录算法训练营Day23

力扣131.分割回文串【medium】
力扣.20组合——剪枝优化【medium】
力扣216.组数总和Ⅲ【medium】

一、力扣131.分割回文串【medium】

题目链接:力扣131.分割回文串
在这里插入图片描述
视频链接:代码随想录、灵茶山艾府

1、思路

  • 回文串是向前和向后读都相同的字符串——用一个-1倒排就可以判断
  • 从答案角度出发:枚举回文字串/逗号结束的位置
  • 递归函数参数:i表示当前处理到字符串的起始位置
  • 终止条件:切割线切到了字符串最后面,说明找到了一种切割方法,i=n
  • 单层搜索的逻辑:遍历所有可能的结束位置j,分割子串s[i.j+1];判断是否回文,是在添加到路径,递归考虑剩余的字串怎么切割,最后pop
  • 注意这边并不需要找到一个path就添加到ans中,而是要都切割完才可以。

在这里插入图片描述

  • 时间复杂度: O ( n ∗ 2 n ) O(n*2^n) O(n2n),其中 n 为 s 的长度。答案的长度至多为逗号子集的个数,即 O ( 2 n ) O(2 ^n) O(2n),因此会递归 O ( 2 n ) O(2 ^n) O(2n)次,再算上判断回文和加入答案时需要 O ( n ) O(n) O(n) 的时间,所以时间复杂度为 O ( n ∗ 2 n ) O(n*2^n) O(n2n)

2、代码

class Solution:
    def partition(self, s: str) -> List[List[str]]:
        n = len(s)
        ans = []
        path = []

        def dfs(i): # i 表示回文子串结束的位置 / 表示当前处理到字符串的起始位置
            # 如果起始位置已经到达字符串末尾,说明当前分割完成
            if i == n:
                ans.append(path.copy())
                return
            # 遍历所有可能的结束位置j,分割子串s[i..j]
            for j in range(i, n):
                t = s[i:j+1]
                if t == t[::-1]:
                    path.append(t)
                    dfs(j+1) # 递归处理剩余子串s[j.+1.n-1]
                    path.pop()  # 回溯,移除当前子串,尝试其他分割方式

        dfs(0)
        return ans 

3、代码问题

  • 太难了,理解的还不到位

二、力扣77.组合——剪枝优化【medium】

题目链接:力扣77.组合——剪枝优化
在这里插入图片描述

视频链接:代码随想录

1、思路

  • 如果还可以选的数i的个数比还需要选的数d = k - len(path)来的小,那就不用继续往下迭代,直接结束
  • 时间复杂度: O ( k ∗ C n k ) O(k*C_n^k) O(kCnk)

2、代码

  • 答案视角
class Solution:
    def combine(self,n:int,k:int) -> List[List[int]]:
        ans = []
        path = []
        def dfs(i):
            d = k - len(path)
            if i < d :
                return
            if len(path) == k:
                ans.append(path.copy())
                return
            for j in range(i, 0, -1):
                path.append(j)
                dfs(j-1)
                path.pop()
        
        dfs(n)
        return ans
        
  • 输出视角
class Solution:
    def combine(Self,n:int,k:int) -> List[List[int]]:
        ans = []
        path = []
        def dfs(i):
            d = k - len(path)
            if d == 0:
                ans.append(path.copy())
                return
            # 不选 i ;如果i比d来的小就必须选了
            if i > d:
                dfs(i-1)
            
            path.append(i)
            dfs(i-1)
            path.pop()
        dfs(n)
        return ans

3、代码问题

  • if i < d : return 可以删掉,在for循环那里的终止区间改成 d-1

三、力扣216.组数总和Ⅲ【medium】

题目链接:力扣216.组数总和Ⅲ【medium】
left =x300
视频链接:代码随想录

1、思路

  • 和组合那题类似,这边多一个目标:k数之和为n,我们可以给dfs多设置一个参数target,表示我们剩余的目标之和
  • 剪枝:如果 t<0 ,说明已经超过目标n,终止.如果 t 大到剩下的 d 个数加起来都不够t > (i * 2 - d + 1) * d // 2,终止
  • 时间复杂度: O ( k ∗ C 9 k ) O(k*C_9^k) O(kC9k)

2、代码

class Solution:
    def combinationSum3(self, k: int, n: int) -> List[List[int]]:
        ans = []
        path = []
        
        def dfs(i,t):
            d = k - len(path)
            if t < 0 or t > (i * 2 - d + 1) * d // 2:
                return
            if len(path) == k:
                ans.append(path.copy())
                return
            for j in range(i, d-1, -1):
                path.append(j)
                dfs(j-1, t-j)
                path.pop()

        dfs(9,n)
        return ans  

3、代码问题

  • 这边不用再额外判断t是否等于0,因为if的那两个判断的就是t大于零或者t小于零的情况

相关文章:

  • 强化学习的epsilon,应该越来越大?还是越来越小?为什么?
  • 面向对象高级(2)
  • Apache与Nginx网站压测对比
  • C语言 共用体和typedef
  • 集群搭建Weblogic服务器!
  • C++学习之金融类安全传输平台项目git
  • 第十五届蓝桥杯C/C++B组省赛真题讲解(分享去年比赛的一些真实感受)
  • 智体知识库:poplang编程语言是什么?
  • 具身机器人中AI(DEEPSEEK)与PLC、驱动器协同发展研究:突破数据困境与指令精确控制(1)
  • System 应用访问 Vendor 库的详细方案
  • 如何将数组转换为对象(键为数组元素,值为 true)
  • 用 Vue 3 + D3.js 实现动态数据流图
  • noscript 标签是干什么的
  • Linux上位机开发实践(关于Qt的移植)
  • 具身智能零碎知识点(三):深入解析 “1D UNet”:结构、原理与实战
  • Python_levl2.3函数
  • 【AutoTest】自动化测试工具大全(Python)
  • 限流、降级、熔断、隔离?
  • 【Hyperlane 】轻松实现大文件分块上传!
  • 六、测试分类
  • 网站怎么做竞价/黑帽seo培训网
  • 网站建设空间多大/百度指数分析平台
  • 太原网站建设开发公司/广州市运营推广公司
  • 深圳好的网站建设公/google搜索网址
  • 网站建设主要做什么/公司官网模板
  • 人大门户网站建设工作/宁波核心关键词seo收费