尝试走一步,如果是最优或者满足解就继续走,不行就退回。一直到走完。
解题基本步骤:
- 定义解空间
- 确定容易的解空间结构,使得回溯法能够方便地探索所有的解空间
- 深度优先探索,并用剪枝函数避免无效的探索
之前遇到的八皇后问题没办法理解,遇到了leetcode的排序问题,嗯我看懂了,并且一直以来的想法终于懂得用代码去实现了,现在觉得自己还是可以理解的。
例题1
给定两个整数 n 和 k,返回 1 … n 中所有可能的 k 个数的组合。
示例:
输入: n = 4, k = 2
输出: [ [2,4], [3,4], [2,3], [1,2], [1,3], [1,4], ]
思想:重要的思想就是[1,2,3,4]排序,把1放入数组中[1],若长度不为k则继续循环,把候选的[2,3,4]为候选,再次调用方法进入下一个循环,2放入数组中[1,2],长度为2,return 然后pop出最后一个数,数组为[1],下一次循环为[1,3],1继续循环,循环完了之后呢,return 到第一层,把2先放入数组。。。。。。
class Solution(object):
def combine(self, n, k):
list1 = [i for i in range(1,n+1)]
end = []
def way(tec, x):
if len(tec) == k:
end.append(tec[:])
return
for j in range(x, n):
tec.append(list1[j])
way(tec, j + 1)
#满足条件后剪枝,退回上一步
tec.pop()
way([], 0)
return end
end=Solution()
print(end.combine(4,2))
例题2:
八皇后问题:
在8*8的格子里,每一行放一个皇后,但是皇后之间不能冲突,不能出现同行或者同列或者是同意斜线上。
思想:判断是否冲突:如果当前的皇后与之前的皇后存在冲突则选下一个位置,不冲突则选择该位置。
n=8
x=[]
X=[]
def conflict(k):
for i in range(k):
#检查是否冲突
if x[k]==x[i] or abs(x[i]-x[k])==abs(i-k):
return True
return False
def qeen(k):
#若已经到底则为正确答案
if k>=n:
X.append(x[:])
else:
#若没到底则继续探索
for i in range(n):
x.append(i)
#如果冲突则后退,没有冲突则进入下一行写一个皇后的选择
if not conflict(k):
qeen(k+1)
x.pop()
#可视化
def show(x):
for i in range(n):
print('. '*(x[i])+'X '+'. '*(n-x[i]-1))
qeen(0)
print(X)
show(X[-1])
[[0, 4, 7, 5, 2, 6, 1, 3], [0, 5, 7, 2, 6, 3, 1, 4], [0, 6, 3, 5, 7, 1, 4, 2], [0, 6, 4, 7, 1, 3, 5, 2], [1, 3, 5, 7, 2, 0, 6, 4], [1, 4, 6, 0, 2, 7, 5, 3], [1, 4, 6, 3, 0, 7, 5, 2], [1, 5, 0, 6, 3, 7, 2, 4], [1, 5, 7, 2, 0, 3, 6, 4], [1, 6, 2, 5, 7, 4, 0, 3], [1, 6, 4, 7, 0, 3, 5, 2], [1, 7, 5, 0, 2, 4, 6, 3], [2, 0, 6, 4, 7, 1, 3, 5], [2, 4, 1, 7, 0, 6, 3, 5], [2, 4, 1, 7, 5, 3, 6, 0], [2, 4, 6, 0, 3, 1, 7, 5], [2, 4, 7, 3, 0, 6, 1, 5], [2, 5, 1, 4, 7, 0, 6, 3], [2, 5, 1, 6, 0, 3, 7, 4], [2, 5, 1, 6, 4, 0, 7, 3], [2, 5, 3, 0, 7, 4, 6, 1], [2, 5, 3, 1, 7, 4, 6, 0], [2, 5, 7, 0, 3, 6, 4, 1], [2, 5, 7, 0, 4, 6, 1, 3], [2, 5, 7, 1, 3, 0, 6, 4], [2, 6, 1, 7, 4, 0, 3, 5], [2, 6, 1, 7, 5, 3, 0, 4], [2, 7, 3, 6, 0, 5, 1, 4], [3, 0, 4, 7, 1, 6, 2, 5], [3, 0, 4, 7, 5, 2, 6, 1], [3, 1, 4, 7, 5, 0, 2, 6], [3, 1, 6, 2, 5, 7, 0, 4], [3, 1, 6, 2, 5, 7, 4, 0], [3, 1, 6, 4, 0, 7, 5, 2], [3, 1, 7, 4, 6, 0, 2, 5], [3, 1, 7, 5, 0, 2, 4, 6], [3, 5, 0, 4, 1, 7, 2, 6], [3, 5, 7, 1, 6, 0, 2, 4], [3, 5, 7, 2, 0, 6, 4, 1], [3, 6, 0, 7, 4, 1, 5, 2], [3, 6, 2, 7, 1, 4, 0, 5], [3, 6, 4, 1, 5, 0, 2, 7], [3, 6, 4, 2, 0, 5, 7, 1], [3, 7, 0, 2, 5, 1, 6, 4], [3, 7, 0, 4, 6, 1, 5, 2], [3, 7, 4, 2, 0, 6, 1, 5], [4, 0, 3, 5, 7, 1, 6, 2], [4, 0, 7, 3, 1, 6, 2, 5], [4, 0, 7, 5, 2, 6, 1, 3], [4, 1, 3, 5, 7, 2, 0, 6], [4, 1, 3, 6, 2, 7, 5, 0], [4, 1, 5, 0, 6, 3, 7, 2], [4, 1, 7, 0, 3, 6, 2, 5], [4, 2, 0, 5, 7, 1, 3, 6], [4, 2, 0, 6, 1, 7, 5, 3], [4, 2, 7, 3, 6, 0, 5, 1], [4, 6, 0, 2, 7, 5, 3, 1], [4, 6, 0, 3, 1, 7, 5, 2], [4, 6, 1, 3, 7, 0, 2, 5], [4, 6, 1, 5, 2, 0, 3, 7], [4, 6, 1, 5, 2, 0, 7, 3], [4, 6, 3, 0, 2, 7, 5, 1], [4, 7, 3, 0, 2, 5, 1, 6], [4, 7, 3, 0, 6, 1, 5, 2], [5, 0, 4, 1, 7, 2, 6, 3], [5, 1, 6, 0, 2, 4, 7, 3], [5, 1, 6, 0, 3, 7, 4, 2], [5, 2, 0, 6, 4, 7, 1, 3], [5, 2, 0, 7, 3, 1, 6, 4], [5, 2, 0, 7, 4, 1, 3, 6], [5, 2, 4, 6, 0, 3, 1, 7], [5, 2, 4, 7, 0, 3, 1, 6], [5, 2, 6, 1, 3, 7, 0, 4], [5, 2, 6, 1, 7, 4, 0, 3], [5, 2, 6, 3, 0, 7, 1, 4], [5, 3, 0, 4, 7, 1, 6, 2], [5, 3, 1, 7, 4, 6, 0, 2], [5, 3, 6, 0, 2, 4, 1, 7], [5, 3, 6, 0, 7, 1, 4, 2], [5, 7, 1, 3, 0, 6, 4, 2], [6, 0, 2, 7, 5, 3, 1, 4], [6, 1, 3, 0, 7, 4, 2, 5], [6, 1, 5, 2, 0, 3, 7, 4], [6, 2, 0, 5, 7, 4, 1, 3], [6, 2, 7, 1, 4, 0, 5, 3], [6, 3, 1, 4, 7, 0, 2, 5], [6, 3, 1, 7, 5, 0, 2, 4], [6, 4, 2, 0, 5, 7, 1, 3], [7, 1, 3, 0, 6, 4, 2, 5], [7, 1, 4, 2, 0, 6, 3, 5], [7, 2, 0, 5, 1, 4, 6, 3], [7, 3, 0, 2, 5, 1, 6, 4]]
. . . . . . . X
. . . X . . . .
X . . . . . . .
. . X . . . . .
. . . . . X . .
. X . . . . . .
. . . . . . X .
. . . . X . . .
基本的框架就是一个判别一个回溯,若满足则继续,若不满足则回溯。