Backtracking 回溯 总结

  • 有recursion一定有backtracking
  • backtracking: 用recursion递归控制for循环嵌套的数量
  • 所有的backtracking回溯算法都可以说是dfs深搜,所有的dfs深搜都可以说是recursion递归。backtracking回溯是更具体的一个分类。(backtracking子类,dfs父类,recursion祖父类)
  • backtracking是纯暴力算法,在一些情况下比一层层for loop好
  • 通常backtracking可以抽象为一棵n-ary tree n叉树。The execution of the backtracking is unfolded as a DFS traversal in a n-ary tree.
  • Time Complexity: The total number of steps during the backtracking would be the number of nodes in the tree.

 

模板

  • 用java存放结果时,要深拷贝,用new ArrayList<>(temp):Java传入的都是temp的地址,所以需要new ArrayList(temp) 这个相当于新创建了一个对象。如果不创建新对象, 我们放入多少个对象都是指向了temp一个对象。回溯的过程会不断remove元素, 浅拷贝的对象会跟着变化,因为地址一样, 所以大家得到的答案预期不一样。
  • 深拷贝:完全赋值一份对象, 地址不同。复制一个一模一样的地址不一样的对象。
  • 浅拷贝:地址一样, 操作同一个对象。默认放进去的对象就是一个浅拷贝。
void backtracking(参数) {
    if (终止条件) {
        存放结果;
        return;
    }

    for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) {
        处理节点;
        backtracking(路径,选择列表); // 递归
        回溯,撤销处理结果
    }
}

StartIndex?

  • Combinations 组合

  • String 切割

    • 切割过的地方,不能重复切割,和组合问题也是保持一致的

  • Permutations 排列

Combinations 组合 (不强调order)

  • 选取一个a之后,在bcdef中再去选取第二个,选取b之后在cdef中在选组第三个.....
  • 一个集合来求组合
    • 77. Combinations, 39. Combination Sum, 40. Combination Sum ii, 216. Combination Sum iii (涉及去重)
    • Number of solutions: _{N}^{k}\textrm{C} = N!/(N-k)!k!
    • Time Complexity: O(2^N * N) 组合问题其实就是一种子集的问题,所以组合问题最坏的情况,也不会超过子集问题的时间复杂度。
  • 多个集合取组合
    • 17. Letter Combinations of a Phone Number
    • Time Complexity: O(4^N * N)
    • Space Complexity: O(N)

String 切割

  • 切割其实类似组合问题:切割一个a之后,在bcdef中再去切割第二段,切割b之后在cdef中在切割第三段.....
  • 如何模拟那些切割线
  • 切割问题中递归如何终止
  • 在递归循环中如何截取子串
  • 131. Palindrome Partitioning, 93. Restore IP Address

Subset 子集

  • 子集也是一种组合问题,因为它的集合是无序的,子集{1,2} 和子集{2,1}是一样的
  • 如果把子集问题、组合问题、分割问题都抽象为一棵树的话,那么组合问题和分割问题都是收集树的叶子节点,而子集问题是找树的所有节点
  • 78. Subsets, 90. Subsets ii (涉及去重), 491. Increasing Subsequences(涉及去重)
  • Number of solutions: 2^N Time Complexity: O(2^N * N) since each element could be absent or present.

Permutations 排列 (强调order)

  • 不需要startIndex,每层都是从0开始搜索而不是startIndex
  • 需要used数组记录temp里都放了哪些元素了
  • 46. Permutations, 47. Permutations ii (涉及去重,对比subsets ii)
  • Number of solutions: N! Time Complexity: O(N! * N)每一层节点为n,第二层每一个分支都延伸了n-1个分支,再往下又是n-2个分支,所以一直到叶子节点一共就是 n * n-1 * n-2 * ..... 1 = n!

Graph 拓展

  • backtracking return boolean: 只需要找到一个行程,就是在树形结构中唯一的一条通向叶子节点的路线
  • 332. Reconstruct Itinerary - 一般用dfs

N-Queen, Sudoku 棋盘

  • N皇后问题抽象为一棵树,收集树的叶子节点(递归的深度就是棋盘的高度)
  • Sudoku: 二维递归,每一层两个for loop
  • 51. N Queens
    • Time Complexity: O(N!) 不是O(N^N) 因为皇后之间不能见面,是N*N-1*N-2*... And it costs O(N^2) to build each valid solution
    • Space Complexity: O(N^2) chessboard[][] is N*N. The recursion stack is O(N).
  • 37. Sudoku Solver
    • Time Complexity: Number of operations needed: (9!)^9 Let's consider one row, there are not more than 9 possibilities for the first number to put, not more than 9×8 for the second one, not more than 9×8×7 for the third one etc. In total that results in not more than 9! possibilities for a just one row, that means not more than (9!)×(9!)×...×(9!) = (9!)^9 operations in total. 
    • Space Complexity: O(9^2) 二维递归
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值