力扣算法刷题Day27|回溯:组合总和I&II 分割回文串

力扣题目:#39. 组合总和

刷题时长:30min

解题方法:回溯

复杂度分析

  • 时间O(n * 2^n),是一个比较松的上界,即在这份代码中,n 个位置每次考虑选或者不选,如果符合条件,就加入答案的时间代价。但是实际运行的时候,因为不可能所有的解都满足条件,递归的时候我们还会剪枝,所以实际运行情况是远远小于这个上界的。
  • 空间O(target) ,除答案数组外,空间复杂度取决于递归的栈深度,在最差情况下需要递归 O(target)层。

问题总结

  • 组合重复。深度上回溯的startind不可以总从第0个元素开始,应该从广度遍历到的元素开始

本题收获

  • 题目难点:题目已知集合无重复元素,解集不得含有重复组合,组合中允许元素重复出现
  • 画草图:把树的广度和深度画出来有助于解题
  • 剪枝优化:candidates排序后,一旦sum(path) + candidate[i] > target,无需继续遍历深度,直接跳到后一个广度

力扣题目:#40.组合总和II 

刷题时长:30min

解题方法:回溯

复杂度分析

  • 时间O(n * 2^n)
  • 空间O(n)

问题总结

  • 用set给结果去重超时,得在回溯过程中的树层中去重
  • 去重条件写错,在candidates[i] == candidates[i-1]满足的情况下,还需同时满足i > startind才能在树层层面去重,而我错写成了startind > 0,导致树枝层面也被强行去重

本题收获

  • 题目难点:题目已知集合内有重复元素,解集中不得含有重复组合,组合中每个元素只能出现一次。此题难点在去重逻辑。
  • 通用去重技巧:初始化used数组为false,用来记录每个元素是否被使用过。当candidates[i] = candidates[i-1],若同时满足used[i-1] = True,则说明此时在树枝上遍历(深度),无需去重;若used[i-1] = False,则说明此时在树层上遍历,需要执行去重。
  • continue vs return in for loop:continue只跳过剩余并进入下一个i;return直接跳出循环返回
  • startind vs i in for loop:for循环里都需要用i来指代和startind的关系

力扣题目:#131.分割回文串  

刷题时长:参考题解后10min

解题方法:回溯+函数判断回文串

复杂度分析

  • 时间 O(n * 2^n)
  • 空间O(n^2)

问题总结

  • 没能抽象成回溯思路,不知如何模拟切割线

本题收获

  • 题目难点:
    • 切割问题可以抽象为回溯问题:枚举切割线的位置
    • 如何模拟那些切割线:startindex是上一层已经确定了的分割线,i是这一层试图寻找的新分割线
    • 切割问题中递归如何终止:当startindex = len(string),分割线已切到末尾
    • 在递归循环中如何截取子串:string[startindex:i+1]
    • 如何判断回文:双指针一首一尾判断元素是否一致
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值