从for循环入手理解回溯算法之组合问题(新手教学)

1.回溯算法很容易把自己绕晕,但是如果从for循环入手理解,容易达到事半功倍的效果.
2.给定题目:(从1-4中找出2位数的组合)

2.1案例一:我们做此类题的第一思路是用双层for循环,代码如下

def fun(n, k):
	for i in range(1, n+1):
		for j in range(i+1. n+1):
			print(i, j)
res = fun(4, 2)
print(res)
# 输出结果为12,13,14,23,24,34
# 注意range(5,5)是不会输出任何东西的,所以每一层for循环的截止都是n+1

2.2案例二:那么从1-4中找到三位数的组合呢?,依然可以使用三层for循环解决

def fun(n, k):
	for i in range(1,n+1)
		for j in range(i,n+1):
			for m in range(j,n+1):
				print(i,j,m)
res = fun(4,3)
print(res)
# 输出结果
#123 124 134 234

2.3很显然如果我要你求100个数里面的其中某98个数的组合呢?
难道要写98个循环吗?显然是不可能的,因此我们引出了回溯算法求解此类问题.

3.题目转换

题目描述:给定两个整数 n 和 k,返回 1 … n 中所有可能的 k 个数的组合。
3.1根据以上的案例我们可以明显看出一些规律

# 案例一关键代码
for i in range(1, n+1):
		for j in range(i+1. n+1):
			print(i, j)
# 案例二关键代码
for i in range(1,n+1)
		for j in range(i,n+1):
			for m in range(j,n+1):
				print(i,j,m)
# 比较得知:
# 内层循环的范围(m,n),其中m由上一层的循环遍历得出,n固定
# 因此我们可以想到把内层抽取成一个函数的思想,由此引出了递归和回溯
# 抽取后代码
res = [] # 存放最终结果
path = [] # 存放过程结点
def fun(n, k, startIndex): # 范围的第一个参数是变化的,因此设定参数startIndex
	# 终止条件,长度为k的时候,收集
	if len(path) == k:
		res.append(path)
		return
	for i in range(startIndex, n+1):
		# 将第一个值i加入到path中
		path.append(i)
		fun(n, k. i+1) # 这里的i+1,理解一下以上两个案例就知道了
		# 递归之后的回溯过程,防止path累加
		path.pop()

附上一道力扣的题目链接:理解后尝试一下自己实现这道题
组合问题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值