力扣题目:#93.复原IP地址
刷题时长:15min
解题方法:原创回溯法
复杂度分析
- 时间 O(3^4),IP地址最多包含4个数字,每个数字最多有3种可能的分割方式,则搜索树的最大深度为4,每个节点最多有3个子节点。
- 空间 O(n)
问题总结
- path.append(整段符合条件的substring)而非仅仅是此时遍历到的值。因为i代表的是切割位置,而非组合问题中的单个数值。
- leading zeros的要求我只判断了值为0,没有判断此时长度是否超过1。若只是单个0那是符合要求的。
本题收获
- 切割问题如何抽象成组合问题:组合问题是枚举单个数值选择符合条件的s[i],切割问题是枚举字符子串选取符合条件的s[startIndex, i],(区间左闭右闭)
- 剪枝优化:if len(path) > 3: break
- 回溯解题思路:
- 返回值:无;参数:string,startIndex
- 终止条件:len(path) == 4 and startIndex == len(string)
- 单层逻辑:判断从startIndex到i区间的子串是否符合valid IP字段要求,若不符合则直接break跳出循环;若符合,则将子串加入path答案,并从后一位开始递归枚举为切割线
力扣题目:#78.子集
刷题时长:10min
解题方法:回溯
复杂度分析
- 时间O(n * 2^n)
- 空间O(n)
问题总结
- 什么时候return,什么时候收集答案
本题收获
- 什么时候return:当到叶子节点时return,即当startIndex已经大于数组的长度了,就终止了,因为没有元素可取了。其实可以不需要加终止条件,因为startIndex >= nums.size(),本层for循环本来也结束了。
- 子集问题是收集树的所有节点,组合和分割问题是只收集叶子节点
力扣题目:#90.子集II
刷题时长:25min
解题方法:回溯
复杂度分析
- 时间O(n * 2^n)
- 空间O(n)
问题总结
- 去重之前没有先对集合排序
本题收获
- 利用used数组