当代程序员必备技能(算法)之:递归详解

必备算法:递归!无论你是前端开发,还是后端开发,都需要掌握它! 递归是一种非常重要的算法思想,无论你是前端开发,还是后端开发,都需要掌握它。在日常工作中,统计文件夹大小,解析xml文件等等,都需要用到递归算法。它太基础太重要了,这也是为什么面试的时候,面试官经常让我们手写递归算法。本文呢,将跟大家一起深入挖掘一下递归算法~ 什么是递归? 递归,在计算机科学中是指一种通过重复将问题分解为同类的子问题而解决问题的方法。简单来说,递归表现为函数调用函数本身。在知乎看到一个比喻递归的例子,个人觉得非常形象,大家看一下: ❝ 递归最恰当的比喻,就是查词典。我们使用的. 阅读详情

前言

递归是一种非常重要的算法思想,无论你是前端开发,还是后端开发,都需要掌握它。在日常工作中,统计文件夹大小,解析xml文件等等,都需要用到递归算法。它太基础太重要了,这也是为什么面试的时候,面试官经常让我们手写递归算法。本文呢,将跟大家一起学习递归算法~

  • 什么是递归?
  • 递归的特点
  • 递归与栈的关系
  • 递归应用场景
  • 递归解题思路
  • leetcode案例分析
  • 递归可能存在的问题以及解决方案

什么是递归?

递归,在计算机科学中是指一种通过重复将问题分解为同类的子问题而解决问题的方法。简单来说,递归表现为函数调用函数本身。在知乎看到一个比喻递归的例子,个人觉得非常形象,大家看一下:

❝

递归最恰当的比喻,就是查词典。我们使用的词典,本身就是递归,为了解释一个词,需要使用更多的词。当你查一个词,发现这个词的解释中某个词仍然不懂,于是你开始查这第二个词,可惜,第二个词里仍然有不懂的词,于是查第三个词,这样查下去,直到有一个词的解释是你完全能看懂的,那么递归走到了尽头,然后你开始后退,逐个明白之前查过的每一个词,最终,你明白了最开始那个词的意思。

❞

来试试水,看一个递归的代码例子吧,如下:

public int sum(int n) {
    if (n <= 1) {
        return 1;
    } 
    return sum(n - 1) + n; 
}

递归的特点

实际上,递归有两个显著的特征,终止条件和自身调用:

  • 自身调用:原问题可以分解为子问题,子问题和原问题的求解方法是一致的,即都是调用自身的同一个函数。
  • 终止条件:递归必须有一个终止的条件,即不能无限循环地调用本身。

结合以上demo代码例子,看下递归的特点:

程序员必备的基本算法:递归详解

 

递归与栈的关系

其实,递归的过程,可以理解为出入栈的过程的,这个比喻呢,只是为了方便读者朋友更好理解递归哈。以上代码例子计算sum(n=3)的出入栈图如下:

程序员必备的基本算法:递归详解

 

为了更容易理解一些,我们来看一下 函数sum(n=5)的递归执行过程,如下:

程序员必备的基本算法:递归详解

 

  • 计算sum(5)时,先sum(5)入栈,然后原问题sum(5)拆分为子问题sum(4),再入栈,直到终止条件sum(n=1)=1,就开始出栈。
  • sum(1)出栈后,sum(2)开始出栈,接着sum(3)。
  • 最后呢,sum(1)就是后进先出,sum(5)是先进后出,因此递归过程可以理解为栈出入过程啦~

递归的经典应用场景

哪些问题我们可以考虑使用递归来解决呢?即递归的应用场景一般有哪些呢?

  • 阶乘问题
  • 二叉树深度
  • 汉诺塔问题
  • 斐波那契数列
  • 快速排序、归并排序(分治算法也使用递归实现)
  • 遍历文件,解析xml文件

递归解题思路

解决递归问题一般就三步曲,分别是:

  • 第一步,定义函数功能
  • 第二步,寻找递归终止条件
  • 第二步,递推函数的等价关系式

这个递归解题三板斧理解起来有点抽象,我们拿阶乘递归例子来喵喵吧~

1.定义函数功能

定义函数功能,就是说,你这个函数是干嘛的,做什么事情,换句话说,你要知道递归原问题是什么呀?比如你需要解决阶乘问题,定义的函数功能就是n的阶乘,如下:

//n的阶乘(n为大于0的自然数)
int factorial (int n){

}

2.寻找递归终止条件

递归的一个典型特征就是必须有一个终止的条件,即不能无限循环地调用本身。所以,用递归思路去解决问题的时候,就需要寻找递归终止条件是什么。比如阶乘问题,当n=1的时候,不用再往下递归了,可以跳出循环啦,n=1就可以作为递归的终止条件,如下:

//n的阶乘(n为大于0的自然数)
int factorial (int n){
    if(n==1){
      return 1;
    }
}

3.递推函数的等价关系式

递归的「本义」,就是原问题可以拆为同类且更容易解决的子问题,即「原问题和子问题都可以用同一个函数关系表示。递推函数的等价关系式,这个步骤就等价于寻找原问题与子问题的关系,如何用一个公式把这个函数表达清楚」。阶乘的公式就可以表示为 f(n) = n * f(n-1), 因此,阶乘的递归程序代码就可以写成这样,如下:

int factorial (int n){
    if(n==1){
      return 1;
    }
    return n * factorial(n-1);
}

「注意啦」,不是所有递推函数的等价关系都像阶乘这么简单,一下子就能推导出来。需要我们多接触,多积累,多思考,多练习递归题目滴~

leetcode案例分析

来分析一道leetcode递归的经典题目吧~

❝

原题链接在这里哈:https://leetcode-cn.com/problems/invert-binary-tree/

❞

「题目:」 翻转一棵二叉树。

输入:

     4
   /   \
  2     7
 / \   / \
1   3 6   9

输出:

     4
   /   \
  7     2
 / \   / \
9   6 3   1

我们按照以上递归解题的三板斧来:

「1. 定义函数功能」

函数功能(即这个递归原问题是),给出一颗树,然后翻转它,所以,函数可以定义为:

//翻转一颗二叉树
public TreeNode invertTree(TreeNode root) {
}

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */

「2.寻找递归终止条件」

这棵树什么时候不用翻转呢?当然是当前节点为null或者当前节点为叶子节点的时候啦。因此,加上终止条件就是:

//翻转一颗二叉树
public TreeNode invertTree(TreeNode root) {
    if(root==null || (root.left ==null && root.right ==null)){
       return root;
    }
}

「3. 递推函数的等价关系式」

原问题之你要翻转一颗树,是不是可以拆分为子问题,分别翻转它的左子树和右子树?子问题之翻转它的左子树,是不是又可以拆分为,翻转它左子树的左子树以及它左子树的右子树?然后一直翻转到叶子节点为止。嗯,看图理解一下咯~

程序员必备的基本算法:递归详解

 

首先,你要翻转根节点为4的树,就需要「翻转它的左子树(根节点为2)和右子树(根节点为7)」。这就是递归的「递」的过程啦

程序员必备的基本算法:递归详解

 

然后呢,根节点为2的树,不是叶子节点,你需要继续「翻转它的左子树(根节点为1)和右子树(根节点为3)」。因为节点1和3都是「叶子节点」了,所以就返回啦。这也是递归的「递」的过程~

程序员必备的基本算法:递归详解

 

同理,根节点为7的树,也不是叶子节点,你需要翻转「它的左子树(根节点为6)和右子树(根节点为9)」。因为节点6和9都是叶子节点了,所以也返回啦。

程序员必备的基本算法:递归详解

 

左子树(根节点为2)和右子树(根节点为7)都被翻转完后,这几个步骤就「归来」,即递归的归过程,翻转树的任务就完成了~

程序员必备的基本算法:递归详解

 

显然,「递推关系式」就是:

invertTree(root)= invertTree(root.left) + invertTree(root.right);

于是,很容易可以得出以下代码:

//翻转一颗二叉树
public TreeNode invertTree(TreeNode root) {
    if(root==null || (root.left ==null && root.right ==null){
       return root;
    }
    //翻转左子树
    TreeNode left = invertTree(root.left);
    //翻转右子树
    TreeNode right= invertTree(root.right);
}

这里代码有个地方需要注意,翻转完一棵树的左右子树,还要交换它左右子树的引用位置。

 root.left = right;
 root.right = left;

因此,leetcode这个递归经典题目的「终极解决代码」如下:

class Solution {
    public TreeNode invertTree(TreeNode root) {
         if(root==null || (root.left ==null && root.right ==null)){
           return root;
         }
         //翻转左子树
         TreeNode left = invertTree(root.left);
         //翻转右子树
         TreeNode right= invertTree(root.right);
         //左右子树交换位置~
         root.left = right;
         root.right = left;
         return root;
    }
}

拿终极解决代码去leetcode提交一下,通过啦~

程序员必备的基本算法:递归详解

 

递归存在的问题

  • 递归调用层级太多,导致栈溢出问题
  • 递归重复计算,导致效率低下

栈溢出问题

  • 每一次函数调用在内存栈中分配空间,而每个进程的栈容量是有限的。
  • 当递归调用的层级太多时,就会超出栈的容量,从而导致调用栈溢出。
  • 其实,我们在前面小节也讨论了,递归过程类似于出栈入栈,如果递归次数过多,栈的深度就需要越深,最后栈容量真的不够咯

「代码例子如下:」

/**
 * 递归栈溢出测试
 */
public class RecursionTest {

    public static void main(String[] args) {
        sum(50000);
    }
    private static int sum(int n) {
        if (n <= 1) {
            return 1;
        }
        return sum(n - 1) + n;
    }
}

「运行结果:」

Exception in thread "main" java.lang.StackOverflowError
 at recursion.RecursionTest.sum(RecursionTest.java:13)

怎么解决这个栈溢出问题?首先需要「优化一下你的递归」,真的需要递归调用这么多次嘛?如果真的需要,先稍微「调大JVM的栈空间内存」,如果还是不行,那就需要弃用递归,「优化为其他方案」咯~

重复计算,导致程序效率低下

我们再来看一道经典的青蛙跳阶问题:一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。

绝大多数读者朋友,很容易就想到以下递归代码去解决:

class Solution {
    public int numWays(int n) {
    if (n == 0){
       return 1;
     }
    if(n <= 2){
        return n;
    }
    return numWays(n-1) + numWays(n-2);
    }
}

但是呢,去leetcode提交一下,就有问题啦,超出时间限制了

程序员必备的基本算法:递归详解

 

为什么超时了呢?递归耗时在哪里呢?先画出「递归树」看看:

程序员必备的基本算法:递归详解

 

  • 要计算原问题 f(10),就需要先计算出子问题 f(9) 和 f(8)
  • 然后要计算 f(9),又要先算出子问题 f(8) 和 f(7),以此类推。
  • 一直到 f(2) 和 f(1),递归树才终止。

我们先来看看这个递归的时间复杂度吧,「递归时间复杂度 = 解决一个子问题时间*子问题个数」

  • 一个子问题时间 = f(n-1)+f(n-2),也就是一个加法的操作,所以复杂度是 「O(1)」;
  • 问题个数 = 递归树节点的总数,递归树的总结点 = 2^n-1,所以是复杂度「O(2^n)」。

因此,青蛙跳阶,递归解法的时间复杂度 = O(1) * O(2^n) = O(2^n),就是指数级别的,爆炸增长的,「如果n比较大的话,超时很正常的了」。

回过头来,你仔细观察这颗递归树,你会发现存在「大量重复计算」,比如f(8)被计算了两次,f(7)被重复计算了3次...所以这个递归算法低效的原因,就是存在大量的重复计算!

「那么,怎么解决这个问题呢?」

既然存在大量重复计算,那么我们可以先把计算好的答案存下来,即造一个备忘录,等到下次需要的话,先去「备忘录」查一下,如果有,就直接取就好了,备忘录没有才再计算,那就可以省去重新重复计算的耗时啦!这就是「带备忘录的解法」

我们来看一下「带备忘录的递归解法」吧~

一般使用一个数组或者一个哈希map充当这个「备忘录」。

假设f(10)求解加上「备忘录」,我们再来画一下递归树:

「第一步」,f(10)= f(9) + f(8),f(9) 和f(8)都需要计算出来,然后再加到备忘录中,如下:

程序员必备的基本算法:递归详解

 

「第二步,」 f(9) = f(8)+ f(7),f(8)= f(7)+ f(6), 因为 f(8) 已经在备忘录中啦,所以可以省掉,f(7),f(6)都需要计算出来,加到备忘录中~

程序员必备的基本算法:递归详解

 

「第三步,」 f(8) = f(7)+ f(6),发现f(8),f(7),f(6)全部都在备忘录上了,所以都可以剪掉。

程序员必备的基本算法:递归详解

 

所以呢,用了备忘录递归算法,递归树变成光秃秃的树干咯,如下:

程序员必备的基本算法:递归详解

 

带「备忘录」的递归算法,子问题个数=树节点数=n,解决一个子问题还是O(1),所以「带「备忘录」的递归算法的时间复杂度是O(n)」。接下来呢,我们用带「备忘录」的递归算法去撸代码,解决这个青蛙跳阶问题的超时问题咯~,代码如下:

public class Solution {
    //使用哈希map,充当备忘录的作用
    Map<Integer, Integer> tempMap = new HashMap();
    public int numWays(int n) {
        // n = 0 也算1种
        if (n == 0) {
            return 1;
        }
        if (n <= 2) {
            return n;
        }
        //先判断有没计算过,即看看备忘录有没有
        if (tempMap.containsKey(n)) {
            //备忘录有,即计算过,直接返回
            return tempMap.get(n);
        } else {
            // 备忘录没有,即没有计算过,执行递归计算,并且把结果保存到备忘录map中,对1000000007取余(这个是leetcode题目规定的)
            tempMap.put(n, (numWays(n - 1) + numWays(n - 2)) % 1000000007);
            return tempMap.get(n);
        }
    }
}

去leetcode提交一下,如图,稳了:

程序员必备的基本算法:递归详解程序员必备的基本算法:递归详解

写在最后

既然你们能看到这里说明这篇文章对你们的帮助还是有的,小编可不可以给你们索要一个小小的赞呢。

延伸学习阅读

 

还在为算法烦恼?那你应该还没看过这份Github上70k标星的笔记
视频:暴力递归算法

看完三件事❤️

========

如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:

点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。

关注公众号 『 Java斗帝 』,不定期分享原创知识。

同时可以期待后续文章ing🚀

程序员必备的基本算法:递归详解

微信小程tree组件,无限递归 原理:没什么原理就是无限递归,组件引用组件本身,如果在有子级的情况下才引用。 * 此处对递归原理不是很熟悉的需要注意一个坑,就是在对组件展开和关闭时候。只需要拿到当前坐标对数组对象直接赋值,并不需要去获取所谓的多维坐标数组。不管你的对象在总数组的第几层,他永远在当前数组的第一层 1.1、tree组件:wxml <view> <view wx:for="{{treeArr}}" wx:key="index"> <view class="view_ red" data 阅读详情

相关推荐

《C++递归算法详解》——自己归纳版

一、Introduction 递归算法是一种直接或者间接调用自身函数或者方法的算法。递归算法的实质是把问题分解成规模缩小的同类问题的子问题,然后递归调用方法来表示问题的解。递归算法对解决一大类问题很有效,它可以使算法简洁和易于理解。递归算法,其实说白了,就是程序的自身调用。它表现在一段程序中往往会遇到调用自身的那样一种coding策略,这样我们就可以利用大道至简的思想,把一个大的复杂的问题层层转换...

WangY.H 1万+

程序员必备的基本算法:递归详解

前言 递归是一种非常重要的算法思想,无论你是前端开发,还是后端开发,都需要掌握它。在日常工作中,统计文件夹大小,解析xml文件等等,都需要用到递归算法。它太基础太重要了,这也是为什么面试的时候,面试官经常让我们手写递归算法。本文呢,将跟大家一起学习递归算法~ 什么是递归? 递归的特点 递归与栈的关系 递归应用场景 递归解题思路 leetcode案例分析 递归可能存在的问题以及解决方案 什么是递归? 递归,在计算机科学中是指一种通过重复将问题分解为同类的子问题而解决问题的方法。简单来说,递归

m0_50180963的博客 1165

C++递归算法经典实例详解

小白博客,记录多于科普

Fu4ng 3万+

c++:无限递归

从前有座山,山里有座庙,庙里有个老和尚给小和尚讲故事,讲的什么故事呢?从前有个山,山里有个庙,庙里有个老和尚给小和尚讲故事……递归相信学C++的朋友们都学过,但是朋友们有没有想过这样一个问题:递归一般要求,要有终止条件,那如果没有终止条件,会怎么样。我们知道,递归会占用很多栈内存,特别是复杂的递归程序!这样一来,这程序不爆栈才怪。还会超时,永远返回不了。我举个例子给大家说明什么是无限递归:。实际上,这个的本质就是无限递归。如果真这么写,那可错误大了。那无限递归又会发生什么呢。

2301_78510792的博客 582

递归算法详解

递归调用一种是解决方案,一种是逻辑思想,将一个大工作分为逐渐减小的小工作,比如说一个和尚要搬50块石头,他想,只要先搬走49块,那剩下的一块就能搬完了,然后考虑那49块,只要先搬走48块,那剩下的一块就能搬完了……递归调用就是在当前的函数中呼叫当前的函数并传给相应的参数,这是一个动作,这一动作是层层进行的,直到满足一般情况的的时候,才停止递归调用,开始从最后一个递归调用返回。这个函数叫做fact,它自己调用自己,这个就是一个典型的递归调用,调用过程类似一个栈。

程序猿老樊的博客 1778

递归算法引发的问题及解决方案——单元测试

通过这些方法,我们可以更好地应对递归算法可能出现的问题,并确保算法的正确性和可靠性。在本文中,我们将探讨递归算法可能出现的问题,并介绍如何使用单元测试来发现和解决这些问题。在这个示例中,我们在函数的开头部分添加了对 n 等于 0 和 1 的边界条件的判断。无限递归是递归算法中最常见的问题之一。为了解决边界条件处理不当的问题,我们需要仔细考虑边界情况,并确保在满足边界条件时及时返回正确的结果。为了解决无限递归问题,我们需要确保递归函数具有正确的终止条件,并且在每次递归调用时,参数都朝着终止条件逼近。

BgScratch的博客 439

算法与数据结构:当代程序员必备技能(算法)丨递归详解

前言 递归是一种非常重要的算法思想,无论你是前端开发,还是后端开发,都需要掌握它。在日常工作中,统计文件夹大小,解析xml文件等等,都需要用到递归算法。它太基础太重要了,这也是为什么面试的时候,面试官经常让我们手写递归算法。本文呢,将跟大家一起学习递归算法~ 什么是递归? 递归,在计算机科学中是指一种通过重复将问题分解为同类的子问题而解决问题的方法。简单来说,递归表现为函数调用函数本身。在知乎看到一个比喻递归的例子,个人觉得非常形象,大家看一下: ❝ 递归最恰当的比喻,就是查词典。我们使用的.

致力于C语言C++知识分享! 387

关于Arduino中的常用函数

一、I/O函数 二、时间函数 三、数学函数 abs 返回其参数的无符号值 【abs(12)返回12,abs(-12)也返回12】 constrain 限制一个数字以阻止它超出范围。第一个参数是被限制的数字,第二个参数是范围区间的开始,第三个参数是允许的数字范围区间的结尾。 【constrain(8,1,10)返回8,constrain(11,1,10)返回10,constrain(0,1,10)返回1】 map 将一个范围内的数字映射到另一个范围。第一个参数是要映射到数字,第二个和第三个参数是from范围(

TREE的博客 7323

求n的阶乘的算法框图_当代程序员必备技能(算法)之:递归详解 - Java斗帝之路...

前言递归是一种非常重要的算法思想,无论你是前端开发,还是后端开发,都需要掌握它。在日常工作中,统计文件夹大小,解析xml文件等等,都需要用到递归算法。它太基础太重要了,这也是为什么面试的时候,面试官经常让我们手写递归算法。本文呢,将跟大家一起学习递归算法~什么是递归?递归的特点递归与栈的关系递归应用场景递归解题思路leetcode案例分析递归可能存在的问题以及解决方案什么是递归?递归,在计算机科学...

weixin_39662228的博客 3321

联想拯救者恢复出厂设置全攻略

通过本文介绍的几种方法,你可以轻松地将联想拯救者恢复到出厂系统状态。无论是通过Windows恢复选项、高级启动选项还是一键恢复功能,都能帮助你解决系统问题、清除个人信息或重置软件环境。在重置前,请务必备份重要数据,并确保了解重置的影响。重置完成后,进行适当的系统设置和软件安装,让你的联想拯救者焕然一新,继续为你提供高效、稳定的计算体验。

mmoo_python的博客 3252

Obsidian免费同步全攻略:手把手教你用OneDrive+Remotely Save插件跨设备同步笔记

本文提供了一份详细的Obsidian免费同步方案指南,核心是利用OneDrive云存储与Remotely Save插件实现跨设备笔记同步。文章手把手教学,涵盖插件安装、OneDrive授权配置、桌面端与移动端的同步设置,并解答了常见问题,帮助用户在不依赖官方付费服务的情况下,构建稳定、自主的免费同步工作流。

bash7scripter的博客 849

2024年最全当代程序员必备技能(算法)之:递归详解(1),java技术专家面试题

其他的内容都可以按照路线图里面整理出来的知识点逐一去熟悉,学习,消化,不建议你去看书学习,最好是多看一些视频,把不懂地方反复看,学习了一节视频内容第二天一定要去复习,并总结成思维导图,形成树状知识网络结构,方便日后复习。这里还有一份很不错的《Java基础核心总结笔记》,特意跟大家分享出来目录:部分内容截图:本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录需要这份系统化的资料的朋友,可以点击这里获取turn 1;

2301_82241647的博客 677

突破NER性能瓶颈:BERT与LLM协同的混合架构实践

性能卓越:在多个测试集上,F1分数比单一模型提升5-15%成本可控:相比纯LLM方案,成本降低60%以上易于落地:架构清晰,便于调试和优化这种"专才+通才"的组合思路可以扩展到其他NLP任务中,如关系抽取、事件提取、文本分类等。更精细的流水线优化多模型投票机制在线学习与自适应调整不追求单一模型的万能,而是通过精心设计的组合,让每个组件发挥其独特优势,最终实现系统性能的最优化。欢迎在评论区分享你在NER任务中的实践经验,或者对这个混合架构的改进建议!

Ven%的博客 1022

解密算法王国:揭秘程序员必备技能(超详细)

🟢 解密算法王国:揭秘程序员必备技能(超详细)

✨ 欢迎来到【Seal ^_^ 的优快云博客】!✨ 5773

STM32F103到F407移植OLED,为啥F4屏幕不亮?一个延时函数搞定时序问题

本文详细分析了STM32F103到F407移植OLED时屏幕不亮的问题,指出时钟频率差异导致的时序问题是关键原因。通过对比F103和F407的时钟架构差异,提供了精确延时函数的实现方法,并指导在I2C通信关键点插入适当延时,确保OLED正常显示。文章还涵盖了完整的测试方案和高级优化技巧,帮助开发者彻底解决移植中的时序问题。

weixin_30642561的博客 549

LibTV保姆级教程:从提示词到AI视频成片全流程

AI视频生成技术正以前所未有的速度重塑内容创作行业,过去需要编剧、摄影、剪辑等多角色协作的复杂流程,如今借助AI绘画与图生视频等核心能力,一个人也能完成高质量短视频制作。理解提示词工程是掌控AI视频创作的关键,通过精准描述主体、环境、光线与运镜,可以显著提升生成画面的稳定性与专业度。而图生视频技术则让静态分镜自然流动,有效解决角色一致性与场景漂移等常见问题。这类工具已广泛应用于产品宣传、剧情短片、社交媒体内容生产等场景,大幅降低了视频创作门槛。本文以LibTV一站式AI视频创作平台为例,从核心概念到完整实操

weixin_29046035的博客 963

程序员必备算法——排列组合

程序员必备算法——排列组合 程序员必备算法排列组合还记得排列组合吗 全排列的实现 组合问题 总结 还记得排列组合吗? 在高中的时候最常接触的莫过于排列组合了,毕竟高考必考的嘛。我们先来回忆下这两个的公式是啥:如果看到这个还有一丢丢的印象,说明大家的基础都还不错。那么问题来了,大家都是学计算机的,我们如何用程序去模拟这个过程,从而达到列出所有排列组合的可能呢? 全排列的实现 暴力求解(不可取,不可取)

床边的扁豆的博客 1万+

NVIDIA Orin AGX开发环境搭建避坑指南:从Ubuntu 22.04到ROS2完整配置流程

本文详细介绍了NVIDIA Orin AGX开发环境搭建的全流程,从Ubuntu 22.04系统安装到ROS2深度优化,涵盖驱动部署、CUDA环境配置、散热与功耗管理等关键步骤。特别针对Orin AGX的特性提供了实用避坑指南和性能优化技巧,帮助开发者高效完成开发环境配置。

weixin_28340315的博客 451

递归算法(图文详解)

递归算法说简单点即就是自身程序的调用,若你掌握递归相应逻辑,递归之时你便可以起飞!!!

lltqyl的博客 13万+

【3天快速入门WPF】8-数据绑定基础

以下是一个简单的 WPF 数据绑定示例,使用两个TextBox控件分别表示Name和Age来进行进行数据绑定试验。运行程序后,你会看到初始界面中TextBox 中显示初始名字 “张三”,TextBox 中显示初始年龄 “25”。在 XAML 中创建一个简单的界面,包含一个 TextBox 用于输入名字,一个 TextBox 用于显示年龄。当你在 TextBox 中修改名字时,Person 对象的 Name 属性会被自动更新,反之亦然。它的主要作用是为控件及其子控件提供一个默认的数据源,用于数据绑定。

Zy100Papa的博客 969

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

递归算法及经典例题详解

递归简单来说就是在运行过程中不断调用自己,直到碰到终止条件,返回结果的过程。递归可以看作两个过程,分别是递和归。递就是原问题把要计算的结果传给子问题;归则是子问题求出结果后,把结果层层返回原问题的过程。下面设一个需要经过三次递归的问题,为大家详细看一下递归的过程:当然,现实中我们遇到递归问题是不会按照图中一样一步一步想下来,主要还是要掌握递归的思想,找到每个问题中的规律。

weixin_45881074的博客 3万+

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

上一篇: 十年资深架构师分享:程序员做哪些准备可以面进BATJ?
下一篇: 阿里突遭断网断电!双11最惊险一幕刚刚曝光
Java斗帝之路
博客等级 码龄7年 2392粉丝 687原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值