递归的本质与基本实现形式

简介: 递归的本质与基本实现形式


递归Recursion

如何理解递归?

  • 函数自身调用自身
  • 通过函数体来进行的循环
  • 以自相似的方法重复进行的过程

计算n!

n! = 1* 2* 3* …* n

def factorial(n):
  if n <= 1:
    return 1
  return n * factorial(n - 1)

啊喂,求n!用递推它不香吗…

确实,因为n!的推导路径我们已经知道了,for一遍就好了。

但如果是不太容易找到推导路径的问题呢?

比如下面的问题,一棵树,在根节点的时候,我们是不知道下边长什么样的…

递归的三个关键:

  • 定义需要递归的问题(重叠子问题)——数学归纳法思维
  • 确定递归边界
  • 保护与还原现场

C++/Java代码模板

void recursion(int level, int param) {
  // terminator
  if (level > MAX_LEVEL) {
    // process result
    return; 
  }
  // process logic in current level
  process(level, param);
  // drill down
  recur(level + 1, new_param);
  // restore the current level status
}

Python代码模板

def recursion(level, param1, param2, ...):
  # recursion terminator
  if level > MAX_LEVEL: 
    # process result
    return
  # process logic in current level
  process(level, data...) 
  # drill down
  self.recursion(level + 1, new_param1, ...) 
  # restore the current level status if needed

实战

78.子集

https://leetcode.cn/problems/subsets/

class Solution {
public:
    vector<vector<int>> subsets(vector<int>& nums) {
        n = nums.size();
        recur(nums,0);
        return ans;
    }
private:
    void recur(vector<int>& nums, int i){
        if(i == n){
            ans.push_back(chosen);
            return;
        }
        recur(nums, i + 1);
        chosen.push_back(nums[i]);
        recur(nums, i + 1);
        chosen.pop_back();
    }
    int n;
    vector<int> chosen;
    vector<vector<int>> ans;
};

77.组合

https://leetcode.cn/problems/combinations/

class Solution {
public:
    vector<vector<int>> combine(int n, int k) {
        this->n = n;
        this->k = k;
        recur(1);
        return ans;
    }
private:
    void recur(int i) {
        if(chosen.size() > k || chosen.size() + (n - i + 1) < k) return;
        if(i == n + 1){
            ans.push_back(chosen);
            return;
        }
        recur(i + 1);
        chosen.push_back(i);
        recur(i + 1);
        chosen.pop_back();
    }
    int n, k;
    vector<int> chosen;
    vector<vector<int>> ans;
};

46.全排列

https://leetcode.cn/problems/permutations/

class Solution {
public:
    vector<vector<int>> permute(vector<int>& nums) {
        n = nums.size();
        used = vector<bool>(n, false);
        recur(nums, 0);
        return ans;
    }
private:
    void recur(vector<int>& nums, int pos) {
        if(pos == n){
            ans.push_back(a);
            return;
        }
        for(int i = 0; i < n; i++){
            if(!used[i]){
                a.push_back(nums[i]);
                used[i] = true;
                recur(nums, pos + 1);
                used[i] = false;
                a.pop_back();
            }
        }
    }
    vector<bool> used;
    vector<int> a;
    int n;
    vector<vector<int>> ans;
};

47.全排列 ||

https://leetcode.cn/problems/permutations-ii/

class Solution {
public:
    vector<vector<int>> permuteUnique(vector<int>& nums) {
        sort(nums.begin(), nums.end());
        vector<vector<int> > res;
        do{
            res.emplace_back(nums);
        }while(next_permutation(nums.begin(), nums.end()));
        return res;
    }
};

递归基本形式总结

以上问题都是递归实现的“暴力搜索”(或者叫枚举、回溯等)

可以总结为以下三种基本形式

推荐一个零声学院免费公开课程,个人觉得老师讲得不错,分享给大家:Linux,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK等技术内容,立即学习

相关文章
|
数据可视化 算法
大白话理解递归本质,可视化递归过程
大白话理解递归本质,可视化递归过程
237 0
|
JavaScript
你能给出几种实现数组扁平化的方法?
扁平化数组没听过?那应该听说过扁平化管理吧,这可是互联网公司面试时的通用话术。简单的说,扁平化就是减少层级,可根据需要减少一个层级,或者减少到只有一个层级。扁平化数组就是将多重嵌套的数组,重新整理成一维数组。接下来就来看看可以怎么实现这种效果吧。
265 0
你能给出几种实现数组扁平化的方法?
|
9月前
|
机器学习/深度学习 编译器 C语言
关于函数递归的基础
关于函数递归的基础
62 5
一个有意思的递归定义
最近在看一本《WEB全栈工程师的自我修养》一书,其中涉及到了npm这个词的意义,非常有意思。 一般人可能以为npm是Node Package Manager的缩写,但实际上不是这样的,npm不是Node Package Manager的首字母缩写,所以不能全大写。
752 0
数据结构与算法__08--霍夫曼树二叉树遍历:1.写在节点类中,在上层调用;2.写在主函数中一次性整体完成
霍夫曼树二叉树遍历:1.写在节点类中,在上层调用;2.写在主函数中一次性整体完成
|
9月前
|
算法 Python
函数的概念和函数表达式的几种形式是什么?
函数的概念和函数表达式的几种形式是什么?
|
9月前
|
Java 程序员
揭秘编程世界的构造块:一文教你理解方法的本质与运用
揭秘编程世界的构造块:一文教你理解方法的本质与运用
54 0

热门文章

最新文章