前端算法学习-递归

188 阅读1分钟

递归是什么?

递归本质上是通过循环体调用自己来进行所谓循环


递归的使用

在日常工作开发中,使用递归时要尽量清晰方法内部结构,建议具备以下几点:

  1. 递归终止条件
  2. 处理当前层级逻辑
  3. 进入下一层(调用自己)
  4. 清理当前层(根据场景需要)
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成立,以此类推