穷举法的基本思想是根据题目的部分条件确定答案的大致范围,并在此范围内对所有可能的情况逐一验证,直到全部情况验证完毕。若某个情况验证符合题目的全部条件,则为本问题的一个解;若全部情况验证后都不符合题目的全部条件,则本题无解。穷举法也称为枚举法。
递归的穷举问题
- 经典算法求{a, b, c}的子集
数学求解可以很快得出有=8个子集, 即
个解.
集合元素较少我们直接罗列出结果来分析下:
{a, b, c} {a, b} {a, c} {a} {b, c} {b} {c} {}
观察所有结果后,重点来了: 每个子集我们可以用{T, T, T} {T, T, F}形式来表示
现在可以把枚举问题转化为决策问题,对每个元素我们都去决策它取或者不取

我们用递归的思想来解决这个问题,对所有情况进行决策,我们把问题拆分,什么时候问题足够小就返回结果,问题足够小从图上可以看到是一条线完全走完,即对每种情况中的元素都做一次决策,剩下的我们继续递归去决策
伪代码分析
function find_subset(全集, 决策){
if(每种情况的元素都做了决策) 返回
每种情况还没有决策完成,递归完成决策
}
- 程序实现
function find_subset(S, decisions){
//如果所有决策都做完我们直接返回决策结果
if(S.length == decisions.length){ //决策是一组true false集合
let decision = []
//根据true/false把对应的元素拿出来
for(let i=0; i<S.length; i++){
if(decisions[i]){
decision.push(S[i])
}
}
return decision.join('')
}
//递归进行决策
let r = []
//对决策执行yes
r = r.concat(find_subset(S, decisions.concat(true)))
//对决策执行no
r = r.concat(find_subset(S, decisions.concat(false)))
//返回结果
return r
}
find_subset(['a','b','c'],decisions=[])
// ["abc", "ab", "ac", "a", "bc", "b", "c", ""]
- 经典案例求''ABC"的全排列
数学求解可以很快得出有3!=6个解, 即n!个解.
观察下结果["ABC", "ACB", "BAC", "BCA", "CAB", "CBA"]
把枚举问题转化为决策问题

如上图转化为决策问题,不同于子集问题,全排列决策是取值ABC产生三种决策取A取B取C,每次去取没取过但存在于原集合的元素
每条决策线可以使用递归来实现
- 伪代码分析
function permutation(str, decisions){
if( 每个decisions决策都已经做完) 直接返回决策结果
每种情况还没有做完决策继续递归完成
}
- 程序实现
function permutation(str, decisions){
//每条决策线路完成我们返回决策结果
if(str.length == decisions.length){
return decisions
}
//没完成决策,继续递归
let r = []
//循环不存在decisions中,在str中的元素
for(let c of str.split('').filter(x => !(decisions.includes(x)))){
r = r.concat(permutation(str, decisions+c))
}
//返回所有结果
return r
}
let oStr = 'ABC'
permutation(oStr, decisions=[])
//["ABC", "ACB", "BAC", "BCA", "CAB", "CBA"]
- 思考
枚举问题转化为决策问题,使用递归可以解决
观察decisions数组,每次递归产生决策占用空间较大
求子集问题可以发现空间复杂度竟达到了 ,如果需要求子集的集合元素有20项,空间消耗太恐怖
可以思考一下有没有更巧妙的做法来对穷举递归进行空间优化!
优化策略下篇将会与大家共同分享
本文探讨了如何使用JavaScript通过递归实现穷举法,特别是针对子集和全排列问题。首先介绍了穷举法的基本思想,然后通过伪代码和程序实例详细解释了递归在决策问题中的应用,以解决{a, b, c}子集和'ABC'全排列的问题。最后,文章指出了递归穷举在空间复杂度上的挑战,并预告将在下篇分享优化策略。"
101916936,8394759,matplotlib图表详解:饼图、箱线图与棉棒图,"['数据可视化', 'matplotlib', 'Python绘图']
2019

被折叠的 条评论
为什么被折叠?



