认识递归

  1. 递归的概念与特性:递归本质类似循环,是通过函数体进行的循环操作。借助电影《盗梦空间》类比,递归如同主角在不同梦境层穿梭,向下进入不同递归层,向上能回到原来一层,每一层环境和周围元素相似,主角在不同层级梦境中会发生变化并携带变化。
  2. 递归的实现——计算n!:计算n的阶乘(n!=1×2×3×…×n)是递归的经典示例。定义Factorial(n)函数,当n <= 1时返回1,否则返回n * Factorial(n - 1) 。以factorial(6)为例,详细展示了递归计算过程。
  3. 递归代码模板
    • Python代码模版recursion(level, param1, param2, ...)函数结构为:先设置递归终止条件(if level > MAX_LEVEL),接着处理当前层逻辑(process(level, data...)),然后向下递归(self.recursion(level + 1, p1, ...)),最后根据需要恢复当前层状态。
    • Java代码模版public void recur(int level, int param)方法同样包含递归终止条件(if (level > MAX_LEVEL))、当前逻辑处理(process(level, param))、向下递归(recur(level: level + 1, newParam))和恢复当前状态(restore current status)这些关键部分。
  4. 递归的思维要点
    • 摒弃人肉递归:避免手动模拟递归过程,这是理解递归的最大误区,应直接依据函数定义编写代码。
    • 分解问题:找到最近最简方法,将问题拆解成可重复解决的子问题,利用重复子问题简化求解。
    • 运用数学归纳法思维:类似点燃炮竹,保证基础情况(第一个炮竹能点燃)成立,假设某一情况(前一个炮竹能点燃)成立时能推出下一个情况(下一个炮竹能点燃)成立,以此构建递归逻辑。

习题

题目描述

给定一个正整数 (n) ,计算 (n) 的阶乘 (n!) ,其中 (n! = 1\times2\times3\times\cdots\times n) ,需用Python语言编写函数实现该计算。

最优解(即图中代码所示方法)

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

解析

  • 递归终止条件if n <= 1: return 1 这部分是递归的关键终止条件。因为 (0!) 和 (1!) 的值都为 (1) ,当函数参数 (n) 为 (0) 或者 (1) 时,直接返回 (1) ,不再继续递归调用,避免无限循环。
  • 递归调用return n * Factorial(n - 1) 体现了阶乘计算的核心逻辑。根据阶乘的定义,(n!) 等于 (n) 乘以 ((n - 1)!) ,所以函数在 (n > 1) 时,通过不断调用自身并将参数减 (1) ,逐步计算出最终结果。比如计算 (5!) ,函数会依次计算 (5\times4!) , (4!) 又会计算为 (4\times3!) ,以此类推,直到遇到终止条件 (1!) 返回 (1) ,再逐步回代计算出最终结果。 这种递归实现简洁且准确地表达了阶乘的计算逻辑。

题目复述

爬楼梯(Climbing Stairs) :假设你正在爬楼梯。需要 n 阶你才能到达楼顶。每次你可以爬 12 个台阶。你有多少种不同的方法可以爬到楼顶呢?(来源:力扣 https://leetcode-cn.com/problems/climbing-stairs/ )

最优解(递归实现思路,实际中更优解一般是迭代等方式 )
def climbStairs(n):if n == 1:return 1if n == 2:return 2return climbStairs(n - 1) + climbStairs(n - 2)
分析
  • 递归终止条件:当 n == 1 时,只有一种爬法,即一次爬一阶,所以返回 1 ;当 n == 2 时 ,可以一次爬两阶,或者分两次每次爬一阶,共两种爬法,返回 2 。这两个条件是递归结束的标志,避免无限递归。
  • 递归调用逻辑:对于 n > 2 的情况,到达第 n 阶楼梯的方法数,等于到达第 n - 1 阶楼梯的方法数加上到达第 n - 2 阶楼梯的方法数。因为到达第 n 阶楼梯,要么是从第 n - 1 阶再爬一阶上来的,要么是从第 n - 2 阶一次爬两阶上来的。所以通过 return climbStairs(n - 1) + climbStairs(n - 2) 进行递归调用,不断将问题规模缩小,直到满足终止条件。

不过需要注意,纯递归实现会存在大量重复计算,时间复杂度较高(指数级) 。实际应用中,更推荐使用迭代法(如动态规划的迭代实现) 、矩阵快速幂等优化方法来降低时间复杂度。

题目描述

爬楼梯问题拓展

假设你正在爬楼梯,需要 n 阶才能到达楼顶,每次你可以爬 1 个、2 个或 3 个台阶 ,求爬到楼顶有多少种不同的方法。

递归实现代码

代码展示
def climbStairs(n):if n == 1:return 1elif n == 2:return 2elif n == 3:return 4return climbStairs(n - 1) + climbStairs(n - 2) + climbStairs(n - 3)

代码解析

递归终止条件
  • n == 1 时 ,只有一种爬法,即一次爬一阶,所以返回 1
  • n == 2 时,有两种爬法:一次爬两阶 ,或者分两次每次爬一阶,返回 2
  • n == 3 时,有四种爬法:(1, 1, 1) 、(1, 2)、(2, 1)、(3) ,返回 4 。这些条件是递归结束的标志,避免无限递归。
递归调用逻辑

对于 n > 3 的情况,到达第 n 阶楼梯的方法数,等于到达第 n - 1 阶楼梯的方法数、到达第 n - 2 阶楼梯的方法数与到达第 n - 3 阶楼梯的方法数之和 。因为到达第 n 阶楼梯,要么是从第 n - 1 阶再爬一阶上来的,要么是从第 n - 2 阶爬两阶上来的,要么是从第 n - 3 阶爬三阶上来的 。所以通过 return climbStairs(n - 1) + climbStairs(n - 2) + climbStairs(n - 3) 进行递归调用,不断将问题规模缩小,直到满足终止条件。

复杂度分析

时间复杂度

由于存在大量重复计算,时间复杂度为指数级,约为 (O(3^n)) ,随着 n 的增大,计算量会急剧增加。

空间复杂度

主要取决于递归调用栈的深度,在最坏情况下为 (O(n)) 。

优化思路

动态规划优化

这种纯递归实现效率较低,存在大量重复计算。可采用动态规划(如使用数组记录中间结果避免重复计算) 、矩阵快速幂等方法优化,将时间复杂度降低。 例如动态规划的迭代实现:

def climbStairs(n):if n == 1:return 1elif n == 2:return 2elif n == 3:return 4dp = [0] * ndp[0], dp[1], dp[2] = 1, 2, 4for i in range(3, n):dp[i] = dp[i - 1] + dp[i - 2] + dp[i - 3]return dp[-1]

此方法用数组 dp 记录爬到第 i 阶的方法数,通过迭代计算,避免了重复计算,时间复杂度降为 (O(n)) ,空间复杂度也为 (O(n)) ,还可进一步优化空间复杂度。

题目描述

给定一个二叉树的根节点 root,判断该二叉树是否为有效的二叉搜索树。在二叉搜索树中,对于任意节点,其左子树中所有节点的值均小于该节点的值,右子树中所有节点的值均大于该节点的值,并且左右子树也都必须是二叉搜索树。

最优解(Python 代码)
# 定义二叉树节点类
class TreeNode:def __init__(self, val=0, left=None, right=None):self.val = valself.left = leftself.right = rightclass Solution:def __init__(self):self.prev = float('-inf')  # 记录中序遍历的前一个节点值,初始化为负无穷def isValidBST(self, root):if not root:return True# 递归检查左子树if not self.isValidBST(root.left):return False# 检查当前节点与前一个节点值的关系if root.val <= self.prev:return Falseself.prev = root.val# 递归检查右子树return self.isValidBST(root.right)
解析
  1. 数据结构定义:首先定义了 TreeNode 类来表示二叉树的节点,每个节点包含一个值 val ,以及指向左子节点 left 和右子节点 right 的指针。这是构建二叉树和进行后续操作的基础。
  2. 类初始化:在 Solution 类的 __init__ 方法中,初始化了一个变量 prev ,并将其值设为负无穷 float('-inf') 。这个变量用于记录在中序遍历过程中前一个节点的值,以便在遍历过程中比较当前节点值与前一个节点值的大小关系,从而判断是否符合二叉搜索树的规则。
  3. 递归函数主体
    • 递归终止条件:当 root 为空节点时,即 not root 条件成立,直接返回 True 。因为空树被定义为有效的二叉搜索树,不存在违反规则的情况。
    • 中序遍历递归检查左子树:通过 self.isValidBST(root.left) 递归调用自身来检查左子树是否为有效的二叉搜索树。如果左子树不是有效的二叉搜索树,直接返回 False ,无需继续检查当前节点和右子树。这是因为只要二叉树的任何一部分不符合规则,整个二叉树就不是有效的二叉搜索树。
    • 检查当前节点:在左子树检查通过后,比较当前节点的值 root.val 和记录的前一个节点的值 self.prev 。如果 root.val <= self.prev ,说明违反了二叉搜索树中序遍历结果应是升序序列的规则(即当前节点值应大于前一个节点值),返回 False 。如果当前节点值符合规则,则更新 self.prev 为当前节点的值 root.val ,为后续检查右子树做准备。
    • 中序遍历递归检查右子树:通过 self.isValidBST(root.right) 递归调用自身来检查右子树是否为有效的二叉搜索树。如果右子树检查通过,说明整个二叉树是有效的二叉搜索树,返回 True ;如果右子树检查不通过,则返回 False
算法复杂度
  • 时间复杂度:该算法需要对二叉树的每个节点进行一次访问,所以时间复杂度为 (O(n)) ,其中 (n) 是二叉树的节点数。
  • 空间复杂度:在递归过程中,递归调用栈的深度最大为二叉树的高度 (h) 。在最坏情况下(二叉树为单链表形式),高度 (h = n) ,此时空间复杂度为 (O(n)) ;在最好情况下(二叉树为完全平衡树),高度 (h = \log n) ,空间复杂度为 (O(\log n)) 。

题目描述(翻转二叉树 - Invert Binary Tree )

给定一棵二叉树的根节点 root ,需要将这棵二叉树进行翻转,也就是交换每个节点的左右子树。例如,对于二叉树 root = [4,2,7,1,3,6,9] ,翻转后应变为 [4,7,2,9,6,3,1] 。(题目来源:https://leetcode-cn.com/problems/invert-binary-tree/description/ )

最优解(递归解法,Python 代码)
# 定义二叉树节点类
class TreeNode:def __init__(self, val=0, left=None, right=None):self.val = valself.left = leftself.right = rightdef invertTree(root):if not root:return None# 交换左右子树root.left, root.right = root.right, root.left# 递归翻转左子树invertTree(root.left)# 递归翻转右子树invertTree(root.right)return root
解析
  1. 递归终止条件:当 root 为空节点时,即 not root ,直接返回 None 。因为空树不需要进行翻转操作。
  2. 交换左右子树:对于非空节点,使用 root.left, root.right = root.right, root.left 这行代码交换当前节点的左右子树。这是翻转二叉树的核心操作,直接改变了当前节点的子树结构。
  3. 递归调用
    • 交换完当前节点的左右子树后,通过 invertTree(root.left) 递归调用函数自身,对当前节点的左子树进行翻转。这是因为左子树在交换后也需要进一步翻转其内部的子树结构。
    • 同理,通过 invertTree(root.right) 递归调用函数自身,对当前节点的右子树进行翻转。
  4. 返回结果:最后返回翻转后的根节点 root ,使得整个翻转操作完成后能得到翻转后的二叉树的根节点,方便后续对整棵树进行操作或访问。
算法复杂度
  • 时间复杂度:由于需要对二叉树的每个节点进行一次访问并交换其左右子树,所以时间复杂度为 (O(n)) ,其中 (n) 是二叉树的节点数。
  • 空间复杂度:在递归过程中,递归调用栈的深度最大为二叉树的高度 (h) 。在最坏情况下(二叉树为单链表形式),高度 (h = n) ,此时空间复杂度为 (O(n)) ;在最好情况下(二叉树为完全平衡树),高度 (h = \log n) ,空间复杂度为 (O(\log n)) 。

题目描述

给定二叉树的根节点 root,求该二叉树的最大深度。二叉树的最大深度是指从根节点到最远叶子节点的最长路径上的节点数 。例如,对于二叉树 [3,9,20,null,null,15,7] ,其最大深度为 3,因为从根节点 3 到叶子节点 157 的路径长度最长,为 3 。(题目来源:https://leetcode-cn.com/problems/maximum-depth-of-binary-tree )

最优解(递归解法,Python 代码)
# 定义二叉树节点类
class TreeNode:def __init__(self, val=0, left=None, right=None):self.val = valself.left = leftself.right = rightdef maxDepth(root):if not root:return 0left_depth = maxDepth(root.left)right_depth = maxDepth(root.right)return max(left_depth, right_depth) + 1
解析
  1. 递归终止条件:当 root 为空节点时,即 not root ,返回 0 。因为空树没有节点,其深度为 0
  2. 递归计算子树深度
    • 通过 left_depth = maxDepth(root.left) 递归调用 maxDepth 函数,计算左子树的最大深度,并将结果存储在 left_depth 变量中。这是因为要得到整棵树的最大深度,需要先知道左子树的最大深度情况。
    • 同理,通过 right_depth = maxDepth(root.right) 递归调用 maxDepth 函数,计算右子树的最大深度,并将结果存储在 right_depth 变量中。
  3. 计算整棵树的最大深度:整棵树的最大深度等于左子树和右子树中较大的深度值再加 1(加 1 是因为要算上根节点本身) ,通过 return max(left_depth, right_depth) + 1 实现这一计算并返回结果。

算法复杂度

  • 时间复杂度:由于需要对二叉树的每个节点进行一次访问,所以时间复杂度为 (O(n)) ,其中 (n) 是二叉树的节点数。
  • 空间复杂度:在递归过程中,递归调用栈的深度最大为二叉树的高度 (h) 。在最坏情况下(二叉树为单链表形式),高度 (h = n) ,此时空间复杂度为 (O(n)) ;在最好情况下(二叉树为完全平衡树),高度 (h = \log n) ,空间复杂度为 (O(\log n)) 。

题目描述

给定一个二叉树的根节点 root,求该二叉树的最小深度。二叉树的最小深度是指从根节点到最近叶子节点的最短路径上的节点数。这里的叶子节点是指没有子节点的节点。例如,对于二叉树 [3,9,20,null,null,15,7] ,其最小深度为 2,因为从根节点 3 到叶子节点 9 的路径长度最短,为 2 。(题目来源:https://leetcode-cn.com/problems/minimum - depth - of - binary - tree )

最优解(Python 递归代码实现)
# 定义二叉树节点类
class TreeNode:def __init__(self, val=0, left=None, right=None):self.val = valself.left = leftself.right = rightdef minDepth(root):if not root:return 0# 如果左子树为空,最小深度取决于右子树if not root.left:return minDepth(root.right) + 1# 如果右子树为空,最小深度取决于左子树if not root.right:return minDepth(root.left) + 1left_depth = minDepth(root.left)right_depth = minDepth(root.right)return min(left_depth, right_depth) + 1
解析
  1. 递归终止条件:当 root 为空节点时,即 not root ,返回 0 。因为空树没有节点,其深度为 0
  2. 特殊情况处理
    • 当左子树为空时,此时二叉树的最小深度取决于右子树,通过 if not root.left: return minDepth(root.right) + 1 来计算,这里加 1 是因为要算上根节点本身。
    • 当右子树为空时,此时二叉树的最小深度取决于左子树,通过 if not root.right: return minDepth(root.left) + 1 来计算,同样加 1 是算上根节点。
  3. 正常情况递归计算:当左右子树都不为空时,分别通过 left_depth = minDepth(root.left)right_depth = minDepth(root.right) 递归计算左子树和右子树的最小深度,然后取两者中的较小值再加 1(加上根节点) ,即 return min(left_depth, right_depth) + 1 ,得到整棵树的最小深度。
算法复杂度
  • 时间复杂度:算法需要遍历二叉树的每个节点,所以时间复杂度为 (O(n)) ,其中 (n) 是二叉树的节点数。
  • 空间复杂度:在递归过程中,递归调用栈的深度最大为二叉树的高度 (h) 。在最坏情况下(二叉树为单链表形式),高度 (h = n) ,此时空间复杂度为 (O(n)) ;在最好情况下(二叉树为完全平衡树),高度 (h = \log n) ,空间复杂度为 (O(\log n)) 。

题目描述

  1. 序列化:给定一棵二叉树的根节点 root,将其按照某种规则转换为一个字符串,这个过程就是序列化。序列化的目的是将二叉树的数据结构以一种可存储或传输的形式表示出来。
  2. 反序列化:给定一个通过序列化得到的字符串数据,将其重新构建成一棵二叉树,这就是反序列化。要求反序列化得到的二叉树与原始二叉树在结构和节点值上完全一致。 (题目来源:https://leetcode-cn.com/problems/serialize - and - deserialize - binary - tree/ )
最优解(Python 代码实现)
# 定义二叉树节点类
class TreeNode:def __init__(self, x):self.val = xself.left = Noneself.right = Noneclass Codec:def serialize(self, root):"""对二叉树进行序列化"""def dfs(node):if not node:res.append('null')returnres.append(str(node.val))dfs(node.left)dfs(node.right)res = []dfs(root)return ','.join(res)def deserialize(self, data):"""对序列化后的字符串进行反序列化"""def helper():val = next(vals)if val == 'null':return Nonenode = TreeNode(int(val))node.left = helper()node.right = helper()return nodevals = iter(data.split(','))return helper()
# 示例用法
# codec = Codec()
# root = TreeNode(1)
# root.left = TreeNode(2)
# root.right = TreeNode(3)
# root.right.left = TreeNode(4)
# root.right.right = TreeNode(5)
# serialized = codec.serialize(root)
# deserialized_root = codec.deserialize(serialized)
解析
  1. 定义二叉树节点类:首先定义 TreeNode 类,用于表示二叉树的节点,每个节点包含节点值 val ,以及指向左子节点 left 和右子节点 right 的指针。
  2. 序列化方法 serialize
    • 内部定义了深度优先搜索(DFS)辅助函数 dfs 。在 dfs 函数中,当遇到空节点时,向结果列表 res 中添加 'null' ,表示空节点。当遇到非空节点时,将节点值转换为字符串添加到 res 中,然后递归调用 dfs 分别处理左子树和右子树。
    • 最后通过 ','.join(res) 将结果列表中的元素以逗号连接成字符串,得到序列化后的结果。
  3. 反序列化方法 deserialize
    • 内部定义了辅助函数 helperhelper 函数通过 next(vals) 从迭代器 vals 中获取下一个值。如果获取到的值是 'null' ,表示当前节点为空,返回 None
    • 如果获取到的值不是 'null' ,则创建一个新的 TreeNode 节点,其值为获取到的值转换后的整数。然后递归调用 helper 分别构建左子树和右子树,最后返回构建好的节点。
    • 通过 vals = iter(data.split(',')) 将输入的序列化字符串按逗号分割后转换为迭代器,方便 helper 函数依次获取节点值或 'null' 标识,最终返回反序列化构建好的二叉树的根节点。
算法复杂度
  • 序列化时间复杂度:在序列化过程中,对二叉树的每个节点进行一次访问,时间复杂度为 (O(n)) ,其中 (n) 是二叉树的节点数。
  • 反序列化时间复杂度:反序列化时,同样要处理序列化字符串中的每个元素(对应二叉树的节点或空节点标识),时间复杂度也是 (O(n)) 。
  • 空间复杂度:无论是序列化还是反序列化,在递归过程中,递归调用栈的深度最大为二叉树的高度 (h) 。在最坏情况下(二叉树为单链表形式),高度 (h = n) ,此时空间复杂度为 (O(n)) ;在最好情况下(二叉树为完全平衡树),高度 (h = \log n) ,空间复杂度为 (O(\log n)) 。此外,序列化结果存储也需要 (O(n)) 的空间。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/76965.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/76965.shtml
英文地址,请注明出处:http://en.pswp.cn/diannao/76965.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux Gitkraken 破解

ubuntu 安装 Gitkraken 9.x Pro 版本_gitcracken.git-CSDN博客

设计模式简述(十一)装饰器模式

装饰器模式 描述基本使用使用 描述 装饰器模式是一种功能型模式 用于动态增强对象的功能 这么一说感觉上和代理模式有些类似 抽象装饰器 要实现原有业务接口&#xff0c;并注入原有业务对象 至于对原有业务对象的调用&#xff0c;可以采用private业务对象 实现业务接口方法的…

【NetCore】ControllerBase:ASP.NET Core 中的基石类

ControllerBase:ASP.NET Core 中的基石类 一、什么是 ControllerBase?二、ControllerBase 的主要功能三、ControllerBase 的常用属性四、ControllerBase 的常用方法2. 模型绑定与验证3. 依赖注入五、ControllerBase 与 Controller 的区别六、实际开发中的最佳实践七、总结在 …

DE2-115分秒计数器

一、模块设计 如若不清楚怎么模块化&#xff0c;请看https://blog.csdn.net/szyugly/article/details/146379170?spm1001.2014.3001.5501 1.1顶层模块 module top_counter(input wire CLOCK_50, // 50MHz时钟input wire KEY0, // 暂停/继续按键out…

ubuntu git cola gui

直接的方法&#xff0c; samba&#xff0c; win 里用 tortoiseSVN 需要先在命令行&#xff0c;运行 git 命令&#xff0c;看到操作提示&#xff0c; 按照提示做 然后右键看 git diff 其它的方法 linux下可视化git工具git-cola安装与使用&#xff08;HTTP方式&#xff09;_git…

每日一题(小白)回溯篇4

深度优先搜索题&#xff1a;找到最长的路径&#xff0c;计算这样的路径有多少条&#xff08;使用回溯&#xff09; 分析题意可以得知&#xff0c;每次向前后左右走一步&#xff0c;直至走完16步就算一条走通路径。要求条件是不能超出4*4的范围&#xff0c;不能重复之前的路径。…

【数据分享】2000—2020年我国250m精度灌溉农田栅格数据(免费获取)

灌溉农田是指通过水利灌溉为农作物提供必要水分&#xff0c;以维持其生长需求的农田类型。灌溉农田占全球农田的20%&#xff0c;占全球粮食产量的40%。但其消耗了60%-70%的淡水和80%-90%的消耗性用水量。中国是世界上灌溉面积最大的农业大国&#xff0c;但中国仅占世界上8%的农…

MySQL-SQL-DML语句、INSER添加数据、UPDATE更新数据、DELETE删除数据

一. DML 1. DML的英文全称是Data Manipulation Language(数据操作语言)&#xff0c;用来对数据库中表的数据记录进行增、删、改操作。 2. 添加数据(INSERT)&#xff1b;修改数据(UPDATE)&#xff1b;删除数据(DELETE) 二. DML-INSER添加数据 -- DML insert -- 指定字段添加数…

使用SymPy求解矩阵微分方程

引言 在数学、物理、工程等领域,微分方程常常被用来描述系统的变化和动态过程。对于多变量系统或者多方程系统,矩阵微分方程是非常常见的,它可以用来描述如电路、控制系统、振动系统等复杂的动态行为。今天,我们将通过Python 中的 SymPy 库来求解矩阵微分方程,帮助大家轻…

Sentinel实战(五)、系统保护规则、限流后统一处理及sentinel持久化配置

Spring Cloud Alibaba-Sentinel实战(五)、系统保护规则、限流后统一处理及sentinel持久化配置 一、系统保护规则一)、系统规则支持的模式二)、新增系统规则界面三)、demo测试二、限流后统一处理实操demo三、sentinel持久化配一、系统保护规则 系统保护规则是从应用级别的…

【百日精通JAVA | SQL篇 | 第四篇】约束

SQL这一块没什么难度&#xff0c;主要是一个熟练度&#xff0c;稍微上点难度的地方&#xff0c;其实在于查&#xff0c;比较复杂&#xff0c;涉及到很多问题。 指定列插入 使用指定列插入的时候&#xff0c;未被指定的列使用默认值进行存储&#xff0c;默认值为空。 默认值设置…

http协议版本的区别 -- 2和3

目录 http2和http3的区别 传输层协议 QUIC协议 介绍 连接建立与握手 建立安全连接的过程 RTT 建连为什么需要两个过程 原因 解决 QUIC协议的1-RTT 建连 必要性 连接过程 第一次握手(Client Hello) 版本号 key_share 其他 第二次握手 介绍 Server Hello 身…

21 天 Python 计划:MySQL 库相关操作

文章目录 前言一、系统数据库1. information_schema2. performance_schema3. mysql4. test 二、创建数据库1. 语法2. 数据库命名规则 三、数据库相关操作1. 查看数据库2. 选择数据库3. 删除数据库4. 修改数据库 总结 前言 Python是一种强大且易于学习的编程语言。通过这个21天的…

手撕LLM(二):从源码出发,探索LoRA加载、推理全流程

接上回接着说&#xff0c;前面我们通过分析源码&#xff0c;了解了大模型推理的详细流程&#xff0c;包括提示词从输入&#xff0c;到对话模版包装&#xff0c;到tokenID转换&#xff0c;到Embedding词向量转换&#xff1b;通过大模型推理&#xff0c;再将大模型输出进行最后一…

WPS宏开发手册——常见问题

目录 系列文章6、常见问题 系列文章 使用、工程、模块介绍 JSA语法 JSA语法练习题 Excel常用Api Excel实战 常见问题 附录 6、常见问题 6.1、编辑完宏后会自动保存&#xff0c;下次打开文件会提醒是否启用宏&#xff0c;点击启用会自动加载上次编辑的…

【Android安卓移动计算】实现项目一[模拟器启动项目]

文章目录 新建项目项目结构介绍说明程序自动生成&#xff1a;图片和样式文件夹&#xff1a;Training1\app\src\main\res\drawable布局文件文件夹&#xff1a;Training1\app\src\main\res\layoutJava文件夹&#xff1a;Training1\app\src\main\java\com\example\training1Androi…

快 速 幂

暴力肯定会超时 3^10 9^5 9*9^4 9*81^2 9*18^2^1 先对b判断奇偶 偶数&#xff1a;对b/2,对a平方 奇数&#xff1a;先*a,再对a平方&#xff0c;b/2 取余注意&#xff1a;(3^10)%k( 9 * 18^2^1)%k(( 9%k )%k * (18^2^1)%k)%k

网络钓鱼攻击的威胁和执法部门的作用(第二部分)

执法部门在打击网络钓鱼中的作用 虽然网络钓鱼可能始于一封欺骗性的电子邮件或短信&#xff0c;但其后果可能远远超出个人收件箱的范围&#xff0c;影响企业、经济甚至国家安全。随着网络钓鱼攻击的规模和复杂性不断增加&#xff0c;执法机构站在前线&#xff0c;努力预防、调…

Data_Socket和UDP_Socket

Data_Socket 和 UDP_Socket 是两种不同类型的网络套接字&#xff0c;它们用于不同的协议和应用场景。以下是它们的主要区别&#xff1a; 协议类型&#xff1a; UDP_Socket&#xff1a;使用的是 UDP&#xff08;User Datagram Protocol&#xff09; 协议&#xff0c;这是一种无连…

2025高频面试算法总结篇【排序】

文章目录 直接刷题链接直达把数组排成最小的数删除有序数组中的重复项求两个排序数组的中位数求一个循环递增数组的最小值数组中的逆序对如何找到一个无序数组的中位数链表排序从一大段文本中找出TOP K 的高频词汇 直接刷题链接直达 把一个数组排成最大的数 剑指 Offer 45. 把…