递归是什么?
递归本质上是通过循环体调用自己来进行所谓循环
递归的使用
在日常工作开发中,使用递归时要尽量清晰方法内部结构,建议具备以下几点:
- 递归终止条件
- 处理当前层级逻辑
- 进入下一层(调用自己)
- 清理当前层(根据场景需要)
const recursion = (level, params) => {
// recursion terminator
if(level > MAX_LEVEL){
process_result
return
}
// process current level
process(level, params)
//drill down
recursion(level+1, params)
//clean current level status if needed
}
递归练习
- 求阶乘(中学数学知识,最基本的递归用法)
/**
* n的阶乘
* @param {*} n
*/
const factorial = (n) => {
if (n < 1) return 1;
return n * factorial(n - 1);
};
- 括号生成
题目:数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。
来源:力扣(LeetCode)
链接:leetcode-cn.com/problems/ge…
示例:
输入:n = 3
输出:[ "((()))", "(()())", "(())()", "()(())", "()()()" ]
/**
* @param {number} n
* @return {string[]}
*/
const generateParenthesis = (n) => {
let result = [];
/**
* @param {*} left 左括号个数
* @param {*} right 右括号个数
* @param {*} n 括号总数
* @param {*} s 括号组合
*/
const recursion = (left, right, n, s) => {
// recursion terminator
if (left === n && right === n) {
result.push(s);
return;
}
//drill down
if (left < n) {
recursion(left + 1, right, n, s + `(`);
}
if (left > right) {
recursion(left, right + 1, n, s + `)`);
}
};
recursion(0, 0, n, ``);
return result;
};
解题思路:
前置条件为n=3,且需考虑括号合法性,不能随意组合,例如:")("
- 左括号在个数不大于3时可以随时追加
- 右括号在数量小于左括号数量时可追加
思维要点
- 不要人肉进行递归
- 尽量避免依赖于手动画递归状态,可根据函数本身思考并锻炼递归思维
- 找到最近最简单方法,将其拆解成可重复解决的问题(重复子问题)
- 数学归纳法思维
- 当n成立时,可以推导出n+1成立,以此类推