c++伪代码_[c-03]leetcode小结[1]-回溯

81484a33db76486457f8eb00d2be3453.png

# 回溯

搜索是把所有可能按照一定的顺序、规则去试探一遍, 从而求出问题的解。

回溯搜索是深度优先搜索(DFS)的一种,主要的区别是:回溯法在求解过程中不保留完整的树结构,而深度优先搜索则记下完整的搜索树。即,回溯法可以被认为是一个有过剪枝的DFS过程。

# 适用情况

序列路径

最优所有可能

# 需要思考 3 个问题:

1、选择路径:已经做出的选择经过的路径。

2、选择列表:当前可以继续选择候选节点(or剪枝)。

3、结束条件:到达决策树底层,无法再做选择的条件。

5ec98621bee52b1f45c919a2f7409d8f.png

# 伪代码

result = []
def backtrack(路径, 选择列表):
    if 满足结束条件:
        result.add(路径)
        return
    
    for 选择 in 选择列表:
        做选择(进入递归节点前的操作)
        backtrack(路径, 选择列表)
        撤销选择(离开递归节点后的操作)

# 相关题目

77. 组合

给定两个整数 nk,返回 1 ... n中所有可能的 k个数的组合。 corner: k==0 vs n<k 路径:无序 选择:因为无序,所以下一层的候选一定不会重复,可以认为是按序递增的。 结束:深度
# 两行代码:递归+数学C(n,k)=C(n-1,k-1)+C(n-1,k).
# corner case
without_last = self.combine(n-1,k)
with_last = [[n] + combo for combo in self.combine(n-1, k-1)]
# return with_last + without_list

39. 组合总和

无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。 corner: not candidates or target == 0 路径:无序 选择:不大于target 结束:等于target、等于数组长度
# 可以用target减去已有路径和,方便写代码
# 剪枝 if candidates[idx] > target: break

40. 组合总和 II

candidates 中的每个数字在每个组合中只能使用一次。 corner: not candidates or target == 0 路径:无序 选择:不大于target 结束:等于target、等于数组长度
# 重复可以先排序 方便剪枝 
# 剪枝 
if candidates[idx] > target: break
if candidates[idx-1] == candidates[idx]:continue

46. 全排列

给定一个 没有重复数字的序列,返回其所有可能的全排列。 corner: 路径: 选择: 结束:等于数组长度
# 剪枝 if visited[idx] == 1: continue
# 节约空间: 可以通过交换完成访问标记
# nums[i], nums[index] = nums[index], nums[i]
# backtrack
# nums[i], nums[index] = nums[index], nums[i]

#  库函数 list(itertools.permutations(nums))

47. 全排列 II

给定一个 有重复数字的序列,返回其所有可能的全排列。 corner: 路径: 选择: 结束:

78. 子集

corner: 路径: 选择: 结束:

90. 子集 II

corner: 路径: 选择: 结束:

22. 括号生成

corner: 路径: 选择: 结束:

# 注意:

  • 举出边界数据,并画出树,有利于写清代码。
  • 写递归的时候,要先写递归终止条件。
  • 注意递归深度和每一层需要完成什么工作。
  • 分析剪枝条件,比如重复就可以优先通过排序解决。

# 参考

leetcode-题解

深度优先搜索和回溯

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值