递归与回溯

概念理解:
递归递归的基本性质就是函数自调用,处理问题时,递归是将一个大问题不断的化为小问题进行处理推导的过程。
回溯利用了递归的性质,从问题的开头出发,不断地尝试,回一步或者是多步在做选择,直到到达终点的一个过程。

递归分析

递归算法是调用自身函数的一中算法(二叉树遍历中得到了广泛应用),可以简单理解,算法是已经实现了解决问题的步骤,使用递归只是将一个大问题不断的变小,直到得出结果。

  • 案例分析1(汉诺塔题目)
// A B C三个柱子,盘子顺序有大到小不能跌倒,将A柱上的盘子移到C柱上

function hanota(A, B, C) {
	// 容错处理:A柱上盘子为空时,不做处理
	if(A.length <= 0)  return C;
	
	// 将 A 上的 n 个盘子移到 C 上
	function move(A, B, C, n) {
		if(n === 0) return;   // 当前柱子上的盘子移动完成
		move(A, C, B, n - 1);   // 借助B,先将 n-1 个盘子移动到 A 上
		C.push(A.pop());        // 将第 n 个盘子从 A 移到 C 上
		move(B, A, C, n - 1);   // 将 n-1 个盘子从 B 移到 C 上(递归处理)
	}
	return move(A, B, C, A.length);
}
  • 案例分析2(中心对称数,详见 LeetCode 247)
/**
* 题目分析:
*	n = 0,返回 [""]
*	n = 1,返回 ["1", "0", "8"]
*	n = 2,返回 ["11", "69", "88", "96"]
*	n = ...
*	以此类推,可见:根据n的值进行判断,满足条件时,只需要在 n-2 的中心对称数上添加
*	["11", "69", "88", "96"] 即可。
*/
function symmetryNUm(n) {
	// 1. 判断输入是否合法
	if(n < 0)  return throw Error("输入有误"); 
	
	// 2. 确定递归结束边界条件
	if(n == 0) return [""];
	if(n == 1) return ["1", "0", "8"];
	
	// 3. 将大问题小化(即为递归处理)
	var list = symmetryNum(n - 2);
	
	// 4. 整合结果
	var res = [];
	for(var i = 0; i < list.length; i++) {
		var temp = list[i];
		res.push("1" + temp + "1");
		res.push("6" + temp + "9");
		res.push("8" + temp + "8");
		res.push("9" + temp + "6");
	}
	return res;
}

总结:
递归步骤:案例2中的解题步骤即为递归步骤;

回溯分析

回溯即为试探算法,当出现非法情况时,可以回退一步或多步,然后去尝试别的路径、情况,因此要实现回溯,需保证每次需要多中可以尝试的可能。
与暴力的区别是:试探,可回退,不满足时可以终止。

解题步骤:

  1. 判断当前是否合法,如果非法立即终止
  2. 当前情况是否满足递归结束条件,如果是将结果保存起来并返回
  3. 当前情况下遍历所有可能出现的情况,进行下一步试探
  4. 递归完毕后立即回溯,(即为取消前一步进行的尝试)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值