当前位置: 首页 > news >正文

【回溯法】——组合总数

回溯核心思想

  • 回溯算法的关键在于:不合适就退回到上一步
  • 具体的:通过枚举法,对所有可能性进行遍历,枚举顺序是一条路走到黑,走到头满足条件后,退一步,再尝试之前没走过的路,直到所有路都走了。

回溯关键点

  • 一条路走到黑
  • 回退一步
  • 另寻他路

实现

  • for循环:

    • 另寻他路:用for循环实现一个路径选择器
    • 逐个选择当前节点下的所有可能往下走的分支路径
    • 例如:走到节点a,向下有i条路,用for循环将这i条路逐个尝试一遍。(进入每条路后递归,重复这个过程)
  • 递归:

    • 一条路走到黑:把递归放在for循环内部,那么for每次循环都在给出一个路径之后进入递归,也就是继续向下走了
    • 回退一步:直到递归出口(无路可走)为止,那么从递归出口出来就会实现回退一步。
  • for循环与递归配合就可以实现回溯:

    • 当递归从递归出口出来后
    • 上一层的for循环就会继续执行
    • 而for循环继续执行就是给出了当前节点的下一条可行路径
    • 而后递归调用,顺着这条从未走过的路径又向下走一步,这就是回溯
def backtracking():# 定义回溯点if (回溯点):  # 这条路走到底了(保存该结果)returnelse:# 逐步选择当前节点下的所有可能路径for route in all_route_set: if (剪枝条件): # 发现当前路不行(剪枝前的操作)return # 不继续往下走了,退回上层,换条路走else:  # 当前路径可行(保存当前数据)  # 向下走之前要记住已经走过了这个节点。保存(调用递归)self.backtracking(xx)  # 递归发生,继续向下走(回溯清理)  # 该节点下的路径都走完了!                        
  • 剪枝:
    • 对于某些问题,走着走着发现这条路不通,再走也是浪费时间和内存
    • 所以直接退回去,切掉这条路

39. 组合总数

39. 组合总和

一、题目难度

中等

二、相关标签与相关企业

[相关标签]
[相关企业]

三、题目描述

给你一个无重复元素的整数数组 candidates 和一个目标整数 target,找出 candidates 中可以使数字和为目标数 target 的所有不同组合,并以列表形式返回。你可以按任意顺序返回这些组合。

candidates 中的同一个数字可以无限制重复被选取。如果至少一个数字的被选数量不同,则两种组合是不同的。

对于给定的输入,保证和为 target 的不同组合数少于150个。

四、示例

示例1

输入

candidates = [2, 3, 6, 7]
target = 7

输出

[[2, 2, 3], [7]]

解释
2和3可以形成一组候选,2 + 2 + 3 = 7。注意2可以使用多次。
7也是一个候选,7 = 7
仅有这两种组合。

示例2

输入

candidates = [2, 3, 5]
target = 8

输出

[[2, 2, 2, 2], [2, 3, 3], [3, 5]]

示例3

输入

candidates = [2]
target = 1

输出

[]

五、提示

  1. 1 <= candidates.length <= 30
  2. 2 <= candidates[i] <= 40
  3. candidates 的所有元素互不相同
  4. 1 <= target <= 40

思路

  1. 解空间:
  • 由输入无重复元素的整数数组candidates=[xxxx]和目标整数target寻找使数字和为目标数的所有不同组合pathresult
  • 同一个数字candidates[i]可以被无限制重复选取
  1. 定义回溯函数参数与终止条件
  • 参数:
    • 输入:无重复元素的整数数组candidates=[xxxx]和目标整数target
    • 可行结果:path
    • 最终结果:result
    • 当前节点:start
  • 核心思想:
    • 不断尝试当前节点可能的路径,将当前节点可走的路径都尝试后,向后移动start ,更新节点位置。(这里不涉及回溯)
    • 回溯的含义是:找到了一条path后,把当前的path末尾的值吐出来,相当于往后退一步,再尝试其他的。
    • 所以这道题回溯点就是“找到了一条路”:当前path满足sum(path) == target。实际代码实现可能涉及直接动target,不一定非这样写!
    • 涉及剪枝:比如某条路,才走了一点,就发现此路不通!某两个节点相加后直接大于了target,那么就没有必要继续走这条路了,直接去掉这个值
  1. 具体代码实现步骤:
  • 再看回溯算法模板,一步步根据这道题背景把代码步骤填进去
def backtracking():# 定义回溯点if (回溯点):  # 这条路走到底了(保存该结果)returnelse:# 逐步选择当前节点下的所有可能路径for route in all_route_set: if (剪枝条件): # 发现当前路不行(剪枝前的操作)return # 不继续往下走了,退回上层,换条路走else:  # 当前路径可行(保存当前数据)  # 向下走之前要记住已经走过了这个节点。保存(调用递归)self.backtracking(xx)  # 递归发生,继续向下走(回溯清理)  # 该节点下的路径都走完了!                        
  • 本题基本机制:target = target - candidates[i]
    • 不断递归,回溯检查target
    • target == 0:走到头,得到一条path,放入result后,回溯,即删掉path最后一个值
    • target < 0: 剪枝
  • 特解:空集candidates,则无结果,return []
  • 初始化回溯函数的参数:
    • 输入:无重复元素的整数数组candidates=[xxxx]和目标整数target
    • 可行结果:path = []
    • 最终结果:result = []
    • 当前节点:start = 0
    • candidates[i]按照从小到大排列好:candidates.sort()
  • 回溯函数:
    • 先定义回溯点:

class Solution:def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:if len(candidates) == 0:return []candidates.sort()path = []res = []'''!!!重点!!!在python中,如果传参是mutable var, 那么传参相当于引用,因此调用后,如果调用函数的内部对该传入变量进行修改,就会导致直接改变原始对象。这就是典型的privacy leak!!发生了。例如在这个,list就是该mutable var,而如果以path或res 为传参,放在__DFS 中, 那么就相当于在__DFS内部,实际上用的都是一个物理地址下的res和path,类似于全局变量。因此combinationSum下的局部变量path和res也在——DFS运行的过程中发生了改变。利用这个性质,我们可以把mutable var当成传入参数,从而实现全局变量的效果。'''self.__DFS(candidates, target, 0, path, res)return res'''DFS的实现'''def __DFS(self, candidates, target, begin, path, res):path = path.copy()# 递归出口 就是余数为0if target == 0:res.append(path)   #记录该符合条件的结果return#若当前路径有可能可行。for i in range(begin, len(candidates)):  # 我们现在到begin的节点上了if target - candidates[i] < 0:  # 剪枝条件return                      # 如果当前节点就不行了,就不用继续了,这里到不用继续了即包括该depth不用继续了,也包括该节点更大到child也不用继续了,该节点pop出来path.append(candidates[i])  #记录当前为止self.__DFS(candidates, target - candidates[i], i, path, res)# 向下继续走,记住递归不是return,递归到实现是调用!一旦return发生,递归停止。path.pop()  # 回朔清理。当前节点下的所有情况都进行完了,该节点也不应该在path里面了。
class Solution:def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:"""主函数,用于调用深度优先搜索(DFS),回溯来解决组合问题,并且返回最终结果:param candidates: 无重复元素的整数数组,从中选取数字组成满足条件target的组合:param target: 目标整数,要使得选取的数字组合的加和达到的值:return: 满足条件的所有不同组合的列表,每个组合都是一个整数列表"""# 特解:candidates空集:if len(candidates) == 0:  # 写成 not candidates 可以么?return []# 对候选数组candidates进行预先排序,方便后续剪枝操作candidates.sort()# 准备回溯函数的参数path = []    # 记录当前正在生成的一种数字组合情况,初始是空列表result = []  # 存储最终所有满足条件的数字组合,初始是空列表# 调用DFS开始回溯过程self.__DFS(candidates, target, 0, path, result)return result# 双下划线约定为“私有”方法,表示类的外部代码不应该直接调用这个函数def __DFS(self, condidates: List[int], target: int, begin: int, path: List[int], result: List[List[int]]):"""深度优先搜索(DFS)函数,用DFS实现回溯算法找出满足条件的数字组合"""# 先对path(上次递归得到的一条路)进行拷贝,# 避免后续操作中直接修改传入的path对象# (因为python中列表是可变对象,传参时可能出现意外修改情况)path = path.copy()# 设置递归出口:当目标值target==0# 说明当前path中的数字组合已经满足和为目标值的条件# 找到了一种满足条件的组合if target == 0:result.append(path)  # 存储path到resultreturn               # 回到上个节点# 遍历从begin位置开始的condidates中的元素# 逐个尝试作为组合的一部分for i in range(begin, len(candidates)):# 剪枝:如果当前值特别大,走到这个值的时候,直接超过了target# 即,target - candidates[i] < 0# 此路不通!return!if target - candidates[i] < 0:return # 否则,将当前数值candidates[i]添加到path,记录正在尝试的组合情况path.append(candidates[i])# 添加后,相当于走到了下一个岔路口# 此时调用递归继续向下一层搜索! # path和result保持不变# 关键点在于,更新目标值为target-candidates[i],表示剩余还需要凑的目标值# 本题更关键的!!!更新begin为i,# 因为candidates[i]可以被重复选择!!!所以暂时不要跳到下一个i+1!!!self.__DFS(candidates, target - candidates[i], i, path, res)# 当下一层递归返回后,说明当前节点下的所有(可重复选)# 可能情况都已经探索完成# 将path的最后一个元素弹出,恢复到添加该元素之前的状态,# 以便尝试下一个数字作为组合的一部分# 继续生成其他可能的满足条件的数字组合path.pop()
————————————————————————————————————————————
执行出错
AttributeError: 'Solution' object has no attribute '_Solution__DFS'^^^^^^^^^^self.__DFS(candidates, target, 0, path, result)
Line 22 in combinationSum (Solution.py)^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ret = Solution().combinationSum(param_1, param_2)
Line 105 in _driver (Solution.py)_driver()
Line 120 in <module> (Solution.py)

这里的错误主要在于内部方法 __DFS 的定义位置和调用方式。

错误分析

在Python中,当你在类的方法内部定义另一个方法时,这样的内部方法不能像你代码中那样直接在类的其他方法中调用。你把 __DFS 方法定义在了 combinationSum 方法内部,这导致在 combinationSum 尝试调用 __DFS 时,Python无法正确识别这个方法,从而报出 'Solution' object has no attribute '_Solution__DFS' 的错误,意思是 Solution 类的实例没有名为 _Solution__DFS 的属性(方法在Python中也被视为属性)。

修正建议

要解决这个问题,你需要把 __DFS 方法定义在和 combinationSum 方法平级的位置,也就是都作为 Solution 类的直接方法,如下所示:

from typing import Listclass Solution:def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:"""主函数,用于调用深度优先搜索(DFS),回溯来解决组合问题,并且返回最终结果:param candidates: 无重复元素的整数数组,从中选取数字组成满足条件target的组合:param target: 目标整数,要使得选取的数字组合的加和达到的值:return: 满足条件的所有不同组合的列表,每个组合都是一个整数列表"""# 特解:candidates空集:if len(candidates) == 0:  # 写成 not candidates 可以么? 可以的,not candidates在candidates为空列表时会返回True,效果相同return []# 对候选数组candidates进行预先排序,方便后续剪枝操作candidates.sort()# 准备回溯函数的参数path = []    # 记录当前正在生成的一种数字组合情况,初始是空列表result = []  # 存储最终所有满足条件的数字组合,初始是空列表# 调用DFS开始回溯过程self.__DFS(candidates, target, 0, path, result)return resultdef __DFS(self, candidates: List[int], target: int, begin: int, path: List[int], result: List[List[int]]):"""深度优先搜索(DFS)函数,用DFS实现回溯算法找出满足条件的数字组合"""# 先对path(上次递归得到的一条路)进行拷贝,# 避免后续操作中直接修改传入的path对象# (因为python中列表是可变对象,传参时可能出现意外修改情况)path = path.copy()# 设置递归出口:当目标值target==0# 说明当前path中的数字组合已经满足和为目标值的条件# 找到了一种满足条件的组合if target == 0:result.append(path)  # 存储path到resultreturn               # 回到上个节点# 遍历从begin位置开始的candidates中的元素# 逐个尝试作为组合的一部分for i in range(begin, len(candidates)):# 剪枝:如果当前值特别大,走到这个值的时候,直接超过了target# 即,target - candidates[i] < 0# 此路不通!return!if target - candidates[i] < 0:return# 否则,将当前数值candidates[i]添加到path,记录正在尝试的组合情况path.append(candidates[i])# 添加后,相当于走到了下一个岔路口# 此时调用递归继续向下一层搜索!# path和result保持不变# 关键点在于,更新目标值为target-candidates[i],表示剩余还需要凑的目标值# 本题更关键的!!!更新begin为i,# 因为candidates[i]可以被重复选择!!!所以暂时不要跳到下一个i + 1!!!self.__DFS(candidates, target - candidates[i], i, path, result)# 当下一层递归返回后,说明当前节点下的所有(可重复选)# 可能情况都已经探索完成# 将path的最后一个元素弹出,恢复到添加该元素之前的状态,# 以便尝试下一个数字作为组合的一部分# 继续生成其他可能的满足条件的数字组合path.pop()

这样修改后,__DFS 作为 Solution 类的一个正常方法,可以在 combinationSum 方法中正确被调用,代码应该能按照预期执行回溯算法来解决组合总和问题。

如果不将 __DFS 方法设置为与 combinationSum 平级(即作为 Solution 类的直接方法),而是想在 combinationSum 方法内部定义并使用类似功能的内部函数来实现回溯逻辑,也是可以的,但需要做一些调整,主要是利用闭包的特性来实现。以下是一种修改后的示例代码:

from typing import Listclass Solution:def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:"""主函数,用于调用内部函数实现回溯来解决组合问题,并返回最终结果:param candidates: 无重复元素的整数数组,从中选取数字组成满足条件target的组合:param target: 目标整数,要使得选取的数字组合的加和达到的值:return: 满足条件的所有不同组合的列表,每个组合都是一个整数列表"""# 特解:candidates空集:if len(candidates) == 0:return []# 对候选数组candidates进行预先排序,方便后续剪枝操作candidates.sort()# 准备回溯函数的参数path = []    # 记录当前正在生成的一种数字组合情况,初始是空列表result = []  # 存储最终所有满足条件的数字组合,初始是空列表# 定义内部函数,利用闭包访问外部函数的变量def inner_DFS(begin):nonlocal path, result, candidates, target# 先对path(上次递归得到的一条路)进行拷贝,# 避免后续操作中直接修改传入的path对象# (因为python中列表是可变对象,传参时可能出现意外修改情况)path = path.copy()# 设置递归出口:当目标值target==0# 说明当前path中的数字组合已经满足和为目标值的条件# 找到了一种满足条件的组合if target == 0:result.append(path)return# 遍历从begin位置开始的candidates中的元素# 逐个尝试作为组合的一部分for i in range(begin, len(candidates)):# 剪枝:如果当前值特别大,走到这个值的时候,直接超过了target# 即,target - candidates[i] < 0# 此路不通!return!if target - candidates[i] < 0:return# 否则,将当前数值candidates[i]添加到path,记录正在尝试的组合情况path.append(candidates[i])# 添加后,相当于走到了下一个岔路口# 此时调用内部函数自身进行递归,继续向下一层搜索!# 注意这里调用的是内部函数inner_DFS,不是之前的平级方法__DFSinner_DFS(i)# 当下一层递归返回后,说明当前节点下的所有(可重复选)# 可能情况都已经探索完成# 将path的最后一个元素弹出,恢复到添加该元素之前的状态,# 以便尝试下一个数字作为组合的一部分# 继续生成其他可能的满足条件的数字组合path.pop()# 调用内部函数开始回溯过程,初始begin为0inner_DFS(0)return result
——————————————————————————
超时!

在上述代码中:

  • 我们在 combinationSum 方法内部定义了一个名为 inner_DFS 的内部函数,它通过 nonlocal 关键字声明了对外部函数(combinationSum)中的一些变量(pathresultcandidatestarget)的引用,这样就可以在内部函数中访问和修改这些外部变量,实现类似之前 __DFS 方法的功能。
  • combinationSum 方法中,通过调用 inner_DFS(0) 来启动回溯过程,就像之前调用 __DFS 方法一样。

这种方式利用了闭包的特性,使得在方法内部定义的函数也能够访问和操作外部函数的相关变量,从而实现回溯算法来解决组合总和问题,但整体代码结构相对来说可能没有将 __DFS 作为平级方法那么清晰直观,所以在实际应用中,更常见的还是将相关的辅助方法定义为类的直接方法(平级),以便于代码的理解和维护。

相关文章:

【回溯法】——组合总数

回溯核心思想 回溯算法的关键在于&#xff1a;不合适就退回到上一步具体的&#xff1a;通过枚举法&#xff0c;对所有可能性进行遍历&#xff0c;枚举顺序是一条路走到黑&#xff0c;走到头满足条件后&#xff0c;退一步&#xff0c;再尝试之前没走过的路&#xff0c;直到所有…...

JavaScript 自动化软件:AutoX.js

<div id"content_views" class"htmledit_views" deep"6"><p></p>...

探索Scala编程:图书管理系统实战

在这篇文章中&#xff0c;我们将通过一个简单的图书管理系统项目来深入理解Scala编程。这个项目不仅会帮助你掌握Scala的基本操作&#xff0c;还会让你了解如何使用Scala来处理实际问题。准备好了吗&#xff1f;让我们开始吧&#xff01; 项目目标 我们的目标是创建一个图书管…...

Java之遍历List集合安全地删除元素

Java之遍历List集合安全地删除元素 在Java中&#xff0c;遍历一个List并安全地删除元素是一个需要注意的问题。因为直接在遍历过程中修改集合&#xff08;如删除元素&#xff09;可能会导致ConcurrentModificationException异常。这是因为集合的迭代器在检测到集合在迭代过程中…...

ceph的集群管理

0 环境说明 ip地址主机名额外硬盘是否加入ceph集群10.0.0.141ceph141sdb 300G&#xff0c;sdc 500G是10.0.0.142ceph142sdb 300G&#xff0c;sdc 500G, sdd 1000G否10.0.0.143ceph143sdb 300G&#xff0c;sdc 500G否 在上一篇文章中&#xff0c;已经成功地初始化了一个ceph管…...

STM32 设计的较为复杂的物联网项目,包括智能家居控制系统,涵盖了硬件和软件的详细设计。

使用 STM32 设计的较为复杂的物联网项目&#xff0c;包括智能家居控制系统&#xff0c;涵盖了硬件和软件的详细设计。 一、硬件设计 微控制器&#xff1a;选择 STM32F4 系列微控制器&#xff0c;如 STM32F407ZGT6&#xff0c;具有高性能和丰富的外设资源。 传感器模块&#x…...

Kettle配置数据源错误“Driver class ‘org.gjt.mm.mysql.Driver‘ could not be found”解决记录

问题描述 错误提示&#xff1a;“Driver class ‘org.gjt.mm.mysql.Driver’ could not be found, make sure the ‘MySQL’ driver (jar file) is installed.” 原因分析&#xff1a; 根据错误提示是缺少了相关的数据源连接jar包。 解决方案&#xff1a; 安装对应的Mysql…...

二分搜索的三种方法

首先总的说一下二分搜索。如果区间具有二分性&#xff0c;这个二分性不仅仅是指区间是有序的&#xff0c;而是我们可以通过某一种性质将整个区间分成左区间和右区间。我们通过二分的方法去不断缩小查找的区间&#xff0c;最终让区间内没有元素&#xff0c;这个时候的我们就得到…...

使用python编写工具:快速生成chrome插件相关文件结构

本文将详细分析一段用 wxPython 编写的 Python 应用程序代码。该程序允许用户创建一些特定文件并将它们保存在指定的文件夹中&#xff0c;同时也能够启动 Google Chrome 浏览器并打开扩展页面&#xff0c;自动执行一些操作。 C:\pythoncode\new\crxiterationtaburl.py 全部代码…...

内存、显存和GPU在Transformer架构中承担什么计算任务

目录 内存、显存和GPU在Transformer架构中承担什么计算任务 一、内存、显存和GPU的区别 二、在Transformer架构中的计算任务 内存、显存和GPU在Transformer架构中承担什么计算任务 是计算机系统中重要的组成部分,它们在Transformer架构中承担着不同的计算任务。以下是对这…...

【计算机网络】TCP协议特点3

心跳机制 什么是心跳机制 心跳机制是在计算机系统、网络通信和许多其他技术领域广泛应用的一种机制&#xff0c;用于检测两个实体之间的连接是否仍然活跃&#xff0c;或者设备是否还在正常运行。就是每隔一段时间发送一个固定的消息给服务端&#xff0c;服务端回复一个固定…...

移植LVGL8.2以及移植过程的理解

一、LVGL刷新显示&#xff08;画点 OR 区域刷新颜色&#xff09; 原来LCD的区域填充&#xff0c;由于没用到DMA就是普通的遍历区域块的坐标&#xff0c;需要传入的坐标就是显示区域的x轴起始与x轴尾部。y轴的起始与y轴的尾部。 怎么实现呢&#xff1f; SPI不加DMA实现区域填充…...

动态规划-背包问题——1049.最后一块石头的重量II

1.题目解析 题目来源 1049.最后一块石头的重量II——力扣 测试用例 2.算法原理 首先需要将该问题转化为0-1背包问题后再做分析 1.状态表示 根据数学中的知识我们知道将一个数字分为两个子数后求这两个子数的最小差值&#xff0c;那么就要求这两个子数尽可能接近于原数字的一…...

【C++学习(37)】并发性模式:如生产者-消费者、读写锁等。 架构模式:如MVC、MVVM等。属于23 种设计模式吗? RAII 的关系?

并发性模式(如生产者-消费者、读写锁等)和架构模式(如 MVC、MVVM 等)并不属于 Gang of Four(GoF) 提出的 23 种经典设计模式 中。这些模式是其他领域中的设计模式,虽然它们和 GoF 的设计模式有交集,尤其是在程序架构和资源管理方面,但并不直接包含在 GoF 的 23 种设计…...

[Mysql] Mysql的多表查询----多表关系(下)

4、操作 方式二&#xff1a;创建表之后设置外键约束 外键约束也可以在修改表时添加&#xff0c;但是添加外键约束的前提是&#xff1a;从表中外键列中的数据必须与主表中主键列中的数据一致或者是没有数据。 语法&#xff1a; alter table <从表名> add constr…...

命名空间(namespace)详解(一)

域 在学习命名空间之前&#xff0c;我们首先要了解几种常见的域 一、域的种类 1、类作用域 类作用域是指定义在类内部的成员&#xff08;包括数据成员和成员函数&#xff09;的可见性和访问权限的范围 代码示例&#xff1a; #define _CRT_SECURE_NO_WARNINGS 1#include &…...

HarmonyOS ArkTs 解决流式传输编码问题

工作日志 日期&#xff1a;2024-11-15 标题&#xff1a;HarmonyOS ArkTs 解决流式传输编码问题 问题描述 问题&#xff1a;在处理流式数据的 HTTP 请求时&#xff0c;服务器返回的数据存在编码问题&#xff0c;导致数据无法正确地解码为字符串。部分数据在解码后出现了乱码…...

NPOI 实现Excel模板导出

记录一下使用NPOI实现定制的Excel导出模板&#xff0c;已下实现需求及主要逻辑 所需Json数据 对应参数 List<PurQuoteExportDataCrInput> listData [{"ItemName": "电缆VV3*162*10","Spec": "电缆VV3*162*10","Uom":…...

【OpenGL】OpenGL简介

文章目录 OpenGL概述OpenGL的本质OpenGL相关库核心库窗口管理glutfreeglutglfw 函数加载glewGLAD OpenGL概述 OpenGL(Open Graphics Library) 严格来说&#xff0c;本身并不是一个API&#xff0c;它是一个由Khronos组织制定并维护的规范(Specification)。OpenGL规范严格规定了…...

shell命令笔记

一、shell基本基础知识 1. shell命令中捕获上一个命令执行是否成功&#xff0c;通过判断 $? 是否为0&#xff0c;为0则表示成功&#xff0c;其他错误码则表示执行失败。 2. sheel命令中&#xff0c;变量赋值时默认都是字符串类型。赋值时须注意单引号与双引号的区别&#xf…...

别再一段段拼了!用UE4蓝图+Spline Component一键生成连续管道/道路模型

UE4蓝图Spline Component自动化生成复杂路径模型实战指南 在游戏开发中&#xff0c;创建蜿蜒的管道、复杂的赛道或是连绵的城墙往往需要耗费大量时间。传统的手动拼接SplineMesh组件的方式不仅效率低下&#xff0c;而且难以保证模型的连续性和一致性。本文将深入探讨如何利用UE…...

番茄小说下载器:3分钟构建个人离线图书馆的终极指南

番茄小说下载器&#xff1a;3分钟构建个人离线图书馆的终极指南 【免费下载链接】Tomato-Novel-Downloader 番茄小说下载器不精简版 项目地址: https://gitcode.com/gh_mirrors/to/Tomato-Novel-Downloader 还在为小说网站广告太多而烦恼吗&#xff1f;想要随时随地离线…...

百度季报图解:营收321亿 AI业务占比首次过半 DAA重塑AI价值标准

雷递网 雷建平 5月18日百度集团&#xff08;纳斯达克&#xff1a;BIDU及香港联交所&#xff1a;9888&#xff08;港元柜台&#xff09;及89888&#xff08;人民币柜台&#xff09;&#xff09;今天公布其截至2026年3月31日止第一季度的未经审计财务业绩&#xff0c;财报显示&am…...

ESPHome安装后,你的第一个智能设备可以不是开关或灯

ESPHome创意实践&#xff1a;从温控风扇到植物管家&#xff0c;解锁智能设备的无限可能 当你完成ESPHome的基础安装后&#xff0c;脑海中浮现的第一个项目是什么&#xff1f;大多数人会想到开关或灯泡——这些确实是智能家居的经典起点。但ESP8266/ESP32开发板的潜力远不止于此…...

AMP插件开发者工具完全指南:如何快速诊断和修复AMP验证问题

AMP插件开发者工具完全指南&#xff1a;如何快速诊断和修复AMP验证问题 【免费下载链接】amp-wp Enable AMP on your WordPress site, the WordPress way. 项目地址: https://gitcode.com/gh_mirrors/am/amp-wp 你是否正在为WordPress网站的AMP验证问题而烦恼&#xff1…...

CVPR2021明星算法LoFTR实战:在Ubuntu 20.04上从零搭建Python 3.7+Pytorch 1.6.0环境,跑通第一个图像匹配Demo

CVPR2021明星算法LoFTR实战&#xff1a;在Ubuntu 20.04上从零搭建Python 3.7Pytorch 1.6.0环境&#xff0c;跑通第一个图像匹配Demo 计算机视觉领域每年都会涌现出大量创新算法&#xff0c;而CVPR2021上发表的LoFTR&#xff08;Detector-Free Local Feature Matching with Tran…...

SQL注入技术详解:从联合查询到盲注实战

前言&#xff1a; 继续开始我们的SQL注入吧&#xff01;本文详细讲解SQL注入的各类技术&#xff0c;包括联合查询、报错注入、布尔盲注、时间盲注、UA注入、Referer注入等&#xff0c;涵盖漏洞判断、利用方法和实战步骤。内容基于MySQL 5.0以上环境&#xff0c;围绕information…...

从直流平衡到时钟恢复:深入剖析8B10B编码在高速串行链路中的核心作用

1. 8B10B编码&#xff1a;高速串行通信的"交通警察" 第一次接触PCIe调试时&#xff0c;我拿着示波器看到波形图上那些密集的跳变信号完全摸不着头脑。直到前辈指着屏幕说&#xff1a;"看见这些有规律的0/1跳变了吗&#xff1f;这就是8B10B在指挥交通。"这个…...

别再为RS485上下拉头疼了!手把手教你搞定RK3568开发板上的ttyS7口(附Qt调试工具源码)

RK3568开发板RS485接口调试实战&#xff1a;从硬件配置到Qt工具开发全解析 在嵌入式系统开发中&#xff0c;RS485通信接口因其抗干扰能力强、传输距离远等优势&#xff0c;被广泛应用于工业自动化、智能家居等领域。然而&#xff0c;许多开发者在RK3568平台上调试RS485接口时&a…...

【免费下载】 AD7124中文手册(非常完整)

AD7124中文手册&#xff08;非常完整&#xff09; 【下载地址】AD7124中文手册非常完整 AD7124-8是一款高性能模拟前端&#xff0c;设计用于在各种苛刻环境中实现精确的数据采集。这款芯片的特点在于其内置的高精度24位Σ-Δ模数转换器(ADC)&#xff0c;能够灵活配置以支持8个差…...