每一个递归都包含回溯,回溯是一种纯暴力搜索方法。每个回溯法都可以抽象为一种N叉树。树的宽度为子集的个数,深度为递归返回的条件。二叉树中的递归都会有回溯算法,只不过有些题目用到了,有些没有用到。
回溯能解决包括组合、排列、切割、子集、棋盘等等问题。
回溯算法就是把栈弹出,恢复到父节点的状态。例如[1,2,3,4]求组合,我们通过递归得到数组[1,2]时,终止条件触发,然后收集结果、return,这时需要把2弹出,恢复到父节点,然后再去递归得到[1,3]。不断回溯、递归。其实就是一个N叉树。
- void backtracking(参数) {
- if (终止条件) {
- 存放结果;
- return;
- }
-
- for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) {
- 处理节点;
- backtracking(路径,选择列表); // 递归
- 回溯,撤销处理结果
- }
- }
给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。
示例 1:
输入:nums = [1,2,3] 输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
- class Solution(object):
- def permute(self, nums):
- """
- :type nums: List[int]
- :rtype: List[List[int]]
- """
- # 回溯,N叉树
- # 全排列
- def backtracking(nums, result, temp):
- if nums == []:
- result.append(temp)
- return
- temp4 = copy.deepcopy(temp)
- for i in range(len(nums)):
- temp2 = nums.pop(0)
- temp.append(temp2)
- backtracking(nums, result, temp)
- nums.append(temp2)
- temp = copy.deepcopy(temp4)
- result = []
- temp = []
- backtracking(nums, result, temp)
-
- return result
