1.回溯法介绍
1.1递归和回溯
每一个递归都包含回溯,回溯是一种纯暴力搜索方法。每个回溯法都可以抽象为一种N叉树。树的宽度为子集的个数,深度为递归返回的条件。二叉树中的递归都会有回溯算法,只不过有些题目用到了,有些没有用到。
1.2回溯能解决的问题
回溯能解决包括组合、排列、切割、子集、棋盘等等问题。
1.3回溯算法的模板
回溯算法就是把栈弹出,恢复到父节点的状态。例如[1,2,3,4]求组合,我们通过递归得到数组[1,2]时,终止条件触发,然后收集结果、return,这时需要把2弹出,恢复到父节点,然后再去递归得到[1,3]。不断回溯、递归。其实就是一个N叉树。
void backtracking(参数) {
if (终止条件) {
存放结果;
return;
}
for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) {
处理节点;
backtracking(路径,选择列表); // 递归
回溯,撤销处理结果
}
}
2.leetcode
2.1第46题-全排列
给定一个不含重复数字的数组 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