二叉树镜像反转就这么简单,99%的人都忽略了这个递归细节

第一章:二叉树镜像反转的核心思想

二叉树的镜像反转是指将树中每个节点的左右子树进行交换,最终得到一棵结构完全对称的新树。这一操作在算法题和实际应用中广泛用于判断树的对称性或实现路径翻转。

基本概念与应用场景

镜像反转后的二叉树在结构上与原树呈左右对称关系。常见于判断一棵树是否为对称树,或作为递归与栈操作的经典练习案例。

实现方式对比

有两种主流实现方式:递归法和迭代法。递归法代码简洁,逻辑清晰;迭代法则借助队列或栈避免深层递归带来的栈溢出问题。
  • 递归法:从根节点开始,交换左右子树,并递归处理子节点
  • 迭代法:使用队列存储待处理节点,逐层进行左右子树交换

递归实现示例(Go语言)


// TreeNode 定义二叉树节点
type TreeNode struct {
    Val   int
    Left  *TreeNode
    Right *TreeNode
}

// mirrorTree 执行镜像反转
func mirrorTree(root *TreeNode) *TreeNode {
    if root == nil {
        return nil
    }
    // 交换左右子树
    root.Left, root.Right = root.Right, root.Left
    // 递归处理左右子节点
    mirrorTree(root.Left)
    mirrorTree(root.Right)
    return root
}
方法时间复杂度空间复杂度
递归法O(n)O(h),h为树高
迭代法O(n)O(w),w为最大宽度
graph TD A[根节点] --> B[左子树] A --> C[右子树] C --> D[新左子树] B --> E[新右子树] style C fill:#f9f,stroke:#333 style B fill:#f9f,stroke:#333

第二章:递归实现的基本原理与结构

2.1 二叉树节点定义与基础操作

在数据结构中,二叉树是一种重要的非线性结构,其每个节点最多有两个子节点:左子节点和右子节点。定义一个二叉树节点通常包含三部分:存储的数据值、指向左子树的指针和指向右子树的指针。
节点结构定义
以Go语言为例,二叉树节点可如下定义:
type TreeNode struct {
    Val   int
    Left  *TreeNode
    Right *TreeNode
}
该结构体中,Val 存储节点值,Left 和 Right 分别指向左、右子树。通过指针串联,形成树形拓扑结构。
基础操作概述
常见的基础操作包括:
  • 节点插入:根据二叉搜索树规则确定插入位置
  • 节点查找:从根节点开始递归比较目标值
  • 遍历操作:前序、中序、后序及层序遍历
这些操作均依赖于节点间的指针引用,是后续高级算法实现的基础。

2.2 镜像反转的递归逻辑拆解

在二叉树结构中,镜像反转的本质是交换每个节点的左右子树。这一操作可通过递归方式简洁实现。
递归终止条件与交换逻辑
当节点为空时,递归终止。否则,先递归处理左右子树,再交换它们的引用。
func mirrorTree(root *TreeNode) *TreeNode {
    if root == nil {
        return nil
    }
    // 递归反转左右子树
    left := mirrorTree(root.Left)
    right := mirrorTree(root.Right)
    // 交换左右子树
    root.Left = right
    root.Right = left
    return root
}
上述代码中,mirrorTree 函数接收根节点并返回反转后的根。递归调用确保深层节点优先处理,回溯时完成自底向上的结构翻转。
时间与空间复杂度分析
  • 时间复杂度:O(n),每个节点访问一次
  • 空间复杂度:O(h),h 为树的高度,源于递归栈深度

2.3 递归终止条件的正确设定

在设计递归算法时,正确设置终止条件是防止无限调用的关键。若终止条件缺失或逻辑错误,将导致栈溢出。
常见终止模式
  • 基于数值边界:如 n ≤ 0 或 n == 1
  • 基于结构状态:如链表节点为 null,树节点为空
  • 基于目标匹配:搜索到目标值即终止
示例:阶乘函数的递归实现
func factorial(n int) int {
    // 终止条件:当 n 为 0 或 1 时返回 1
    if n <= 1 {
        return 1
    }
    return n * factorial(n-1)
}
该代码中,n <= 1 是关键的终止判断。若误写为 n == 0,当传入负数时将陷入无限递归。
边界情况对比
输入值预期行为风险
0正常终止无
-1栈溢出未处理负数

2.4 左右子树交换的执行时机

在二叉树重构过程中,左右子树交换的执行时机直接影响结构对称性与遍历结果。合理的交换策略应结合遍历顺序与业务需求进行判断。
交换触发条件
通常在递归或迭代遍历时决定是否交换。常见场景包括镜像翻转、平衡调整或特定遍历(如后序生成)需要。
  • 先序遍历中交换:优先处理根节点,适用于快速构建镜像树
  • 后序遍历中交换:子树处理完毕后再决策,利于动态结构调整
// 先序交换示例:每访问一个节点即交换其子树
func invertTree(root *TreeNode) *TreeNode {
    if root == nil {
        return nil
    }
    // 执行交换
    root.Left, root.Right = root.Right, root.Left
    invertTree(root.Left)
    invertTree(root.Right)
    return root
}
上述代码在进入子树前完成交换,确保整棵树自上而下逐层翻转。参数说明:输入为根节点指针,递归实现深度优先交换。

2.5 递归调用顺序对结果的影响

在递归函数中,调用顺序直接决定执行路径与最终结果。不同的调用位置可能导致前置处理或后置处理的差异。
先序与后序递归对比
func preOrderPrint(n int) {
    if n <= 0 { return }
    fmt.Println(n)        // 先访问
    preOrderPrint(n-1)    // 再递归
}
该函数先输出当前值再深入递归,输出序列为:3→2→1。
func postOrderPrint(n int) {
    if n <= 0 { return }
    postOrderPrint(n-1)   // 先递归
    fmt.Println(n)        // 后访问
}
后序版本则反向输出:1→2→3,体现调用顺序对执行时序的根本影响。
调用栈行为分析
  • 先序调用减少栈深度前完成操作
  • 后序调用需等待所有子调用返回才执行主体逻辑
  • 顺序选择影响内存占用与结果生成时机

第三章:关键细节的深入剖析

3.1 为什么99%的人忽略递归栈的执行路径

许多开发者在初学递归时,只关注函数“如何调用自己”,却忽视了调用背后的执行上下文堆叠过程。递归的本质是函数调用栈的层层压入与回弹,但这一动态路径常被简化为数学公式推导。
递归执行的隐式栈结构
JavaScript 或 Python 等语言在执行递归时,并非“直接计算结果”,而是依赖调用栈保存每一层的局部变量、返回地址和参数状态。

def factorial(n):
    if n == 0:
        return 1
    return n * factorial(n - 1)  # 当前帧等待子调用完成
以上代码中,factorial(5) 会依次创建 factorial(4) 到 factorial(0) 的栈帧。只有当最深层返回后,各层才能逐级完成乘法运算。
常见误解来源
  • 过度依赖“递推公式”思维,忽略运行时行为
  • 调试器中难以直观查看多层栈的完整状态
  • 教材示例多聚焦边界条件,而非执行轨迹
理解递归栈的展开路径,是掌握复杂递归(如回溯、树遍历)的关键基础。

3.2 指针传递与地址操作的陷阱

在Go语言中,函数参数默认为值传递。当使用指针时,虽可修改原始数据,但也带来潜在风险。
常见错误:空指针解引用
func modify(p *int) {
    *p = 10 // 若p为nil,此处触发panic
}
该代码未校验指针有效性,直接解引用可能导致程序崩溃。应先判断指针是否为空。
陷阱示例:局部变量地址返回
  • 函数返回局部变量的地址,导致悬空指针
  • 堆栈释放后,该地址指向无效内存
安全实践建议
问题解决方案
空指针访问使用前判空检查
非法地址暴露避免返回局部变量地址

3.3 镜像过程中树结构的变化追踪

在分布式文件系统镜像同步中,源端与目标端的目录树结构需保持一致性。为高效追踪变化,通常采用增量扫描机制结合时间戳与哈希校验。
变更检测策略
  • 基于 mtime 的快速比对:识别文件修改时间变化
  • 目录树哈希聚合:每个节点维护子树哈希值,便于快速对比
  • 事件监听(inotify):实时捕获文件系统变更事件
树结构更新示例

type TreeNode struct {
    Path   string
    Hash   string
    MTime  int64
    Children map[string]*TreeNode
}
// UpdateHash 递归计算子树哈希
func (n *TreeNode) UpdateHash() {
    hashes := []string{}
    for _, child := range n.Children {
        child.UpdateHash()
        hashes = append(hashes, child.Hash)
    }
    n.Hash = hash(strings.Join(hashes, "|"))
}
该结构通过递归聚合子节点哈希值,使任意文件变动均反映至根节点哈希,实现整体树结构一致性的快速验证。

第四章:代码实现与调试实践

4.1 完整C语言代码实现示例

基础结构与主函数设计
完整的C语言实现从标准库引入开始,构建清晰的程序入口。以下代码展示了一个带错误处理的主函数框架:
#include <stdio.h>
#include <stdlib.h>

int main() {
    int result = system("echo 'Hello, Embedded World'");
    if (result == -1) {
        fprintf(stderr, "System call failed\n");
        return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;
}
上述代码通过system()调用执行简单命令,适用于嵌入式调试场景。返回值检查确保异常可追溯,EXIT_SUCCESS和EXIT_FAILURE提升代码规范性。
编译与运行说明
  • 使用gcc -o example example.c进行编译
  • 执行./example验证输出结果
  • 建议开启-Wall选项以捕获潜在警告

4.2 构建测试用例验证正确性

在实现功能逻辑后,必须通过系统化的测试用例验证其正确性。测试不仅确保当前行为符合预期,也为后续迭代提供安全保障。
测试用例设计原则
遵循边界值、等价类和异常路径覆盖原则,确保输入场景全面。例如,对数值参数应测试最小值、最大值、零值及非法输入。
使用表驱动测试提升效率
Go语言中推荐使用表驱动方式组织测试用例,结构清晰且易于扩展:

func TestDivide(t *testing.T) {
    cases := []struct {
        a, b     float64
        want     float64
        hasError bool
    }{
        {10, 2, 5, false},
        {5, 0, 0, true},  // 除零错误
    }

    for _, tc := range cases {
        got, err := Divide(tc.a, tc.b)
        if tc.hasError {
            if err == nil {
                t.Fatal("expected error but got none")
            }
        } else {
            if err != nil || got != tc.want {
                t.Errorf("Divide(%f,%f): got %f, want %f", tc.a, tc.b, got, tc.want)
            }
        }
    }
}
该代码定义了多个测试场景,包含正常计算与异常输入。每个用例独立执行,便于定位问题。通过结构体切片集中管理输入与期望输出,显著提升可维护性。

4.3 使用GDB调试递归过程

调试递归函数时,理解调用栈的层级变化至关重要。GDB提供了强大的栈帧查看和断点控制功能,帮助开发者逐层分析递归执行流程。
基础调试命令
常用命令包括 break 设置断点、step 进入函数、finish 执行完当前函数返回上层,以及 backtrace 查看调用栈。
示例代码

int factorial(int n) {
    if (n <= 1) return 1;
    return n * factorial(n - 1); // 递归调用
}
该函数计算阶乘,每次调用自身直至到达基准条件。在GDB中设置断点于递归行,可观察参数 n 的变化趋势。
调用栈分析
  • frame:查看当前栈帧
  • info locals:显示局部变量
  • up/down:在栈帧间移动
通过这些命令,可逐层验证递归状态的正确性。

4.4 常见错误分析与修复策略

空指针异常的典型场景
在对象未初始化时调用其方法是常见错误。例如以下 Go 代码:
type User struct {
    Name string
}

func main() {
    var u *User
    fmt.Println(u.Name) // panic: runtime error: invalid memory address
}
该代码因 u 为 nil 指针导致运行时崩溃。修复方式是确保实例化:u := &User{Name: "Alice"}。
并发访问共享资源问题
多个 goroutine 同时写同一变量会触发数据竞争。可通过互斥锁解决:
var mu sync.Mutex
var counter int

func increment() {
    mu.Lock()
    defer mu.Unlock()
    counter++
}
mu.Lock() 阻止其他协程进入临界区,保障操作原子性。
  • 优先检查初始化流程
  • 使用 -race 参数检测竞态条件
  • 避免在循环中创建 goroutine 而未同步

第五章:从镜像反转看递归思维的本质

递归与树结构的自然契合
在二叉树的镜像反转操作中,递归展现出其最直观的优势。每个节点的左右子树交换依赖于子问题的解,这正是分治思想的核心体现。

// TreeNode 定义二叉树节点
type TreeNode struct {
    Val   int
    Left  *TreeNode
    Right *TreeNode
}

// invertTree 实现镜像反转
func invertTree(root *TreeNode) *TreeNode {
    if root == nil {
        return nil
    }
    // 递归交换左右子树
    root.Left, root.Right = invertTree(root.Right), invertTree(root.Left)
    return root
}
调用栈中的执行轨迹
当输入一个三层满二叉树时,调用栈深度达到3层。每次函数调用都保存当前节点上下文,直到触底(nil)开始回溯并执行交换。
  • 根节点等待其左右子树完成反转后才进行自身交换
  • 递归终止条件避免无限调用,确保程序可终止
  • 每层调用独立处理局部状态,符合函数式编程原则
性能对比分析
方法时间复杂度空间复杂度适用场景
递归实现O(n)O(h)树高度较小,代码简洁性优先
迭代实现O(n)O(w)宽树结构,避免栈溢出
1 1 / \ / \ 2 3 → 3 2 / \ / \ 4 5 5 4
【信息科学与工程学】【数据科学】数据科学领域 第四篇 数据处理05 图形理论与图数据 本表格系统性地整理了分子运动图形图像模拟中涉及的全部核心数学方程分子力学基础:包括力场能量项、键合与非键相互作用的详细表达式分子运动方程:刚体运动、柔性分子运动、约束动力学算法溶剂效应:隐式与显式溶剂模型,连续介质方法量子化学方法:薛定谔方程、分子轨道理论、密度泛函理论分子动力学:积分算法、增强采样技术、自由能计算方法分子对接:打分函数、搜索算法、结合模式分析光谱模拟:红外、拉曼、圆二色性、NMR等光谱的计算方法反应动力学:过渡态理论、势能面、非绝热过程模拟分子可视化。 阅读详情

相关推荐

【信息科学与工程学】【数据中心】第三十二篇 云数据中心的计算/存储/网络的核心挑战01

状态方程: SOCk+1​=SOCk​−Qn​ik​Δt​;: 三相电流变换到αβ坐标系: iα​=32​​(ia​−21​ib​−21​ic​), iβ​=32​​(23​​ib​−23​​ic​). 计算瞬时有功功率p和无功功率q,经低通滤波器分离直流分量,反变换得基波电流,差值即为谐波指令。: 节点i的信念 bi​(xi​)=ϕi​(xi​)∏j∈N(i)​mji​(xi​), 消息 mij​(xj​)=∑xi​​ϕi​(xi​)ψij​(xi​,xj​)∏k∈N(i)\j​mki​(xi​).

weixin_49199313的博客 218

【数据结构】翻转二叉树的三种方式

什么是反转二叉树 反转二叉树的实现方式 方式一:使用栈实现 方式二:使用堆实现 方式三:使用递归来实现

✈ 正在努力 の 寒江(StudiousTiger) ✌ 呐 ✈ 5273

【信息科学与工程学】计算机科学与自动化——第一百八十九篇 计算机硬件 系列一 微处理器01

在金融行业CDN流推送场景中,结合WebRTC over SD-RTN与SD-WAN Branch方案,需兼顾​​要求。

weixin_49199313的博客 1056

翻转二叉树(LeetCode 226)

二叉树翻转是一道经典的面试编程题,经常出现在各大公司的招聘笔试面试环节。这里还有个趣事,Homebrew的作者Max Howell某天去 Google 面试,面试官出了一道翻转二叉树的题目,然而 Max Howell 没答上来,结果被拒。面试官的评语是:“我们 90% 的工程师使用您编写的软件,但是您却无法在面试时在白板上写出翻转二叉树这道题,所以滚蛋吧”。可见,在求职面试过程中,即使你是一位优秀的程序员,如果答不上算法题,那么在算法方面的能力将被面试官认为是不及格的,甚至无法被聘用。

Doublelv 的博客专栏。 3221

【信息科学与工程学】【运营科学】第二篇 C4信息与通信网络运营 (C4) ——数据中心网络运营06

13 | 司法诉讼 | 原告律师 | 争取和解优势 | 证据披露的序贯博弈 | 策略性证据释放 | 持有证据集E = {强证据e_s, 中证据e_m, 弱证据e_w}。设公众原有认知人格向量为 Pold​​=(p1​,p2​,...,pk​), 其中p_i为负面特质(如“不敬业”)。危机后, 通过行为序列 {At​}和宣传, 将公众认知向新向量 Pnew​​引导, 使得在关键维度上, Pnew​​与 Pold​​的余弦相似度降低, 并与一个正面的、可接受的“原型”(如“浪子回头”、“慈父”)对齐。

weixin_49199313的博客 1482

【信息科学与工程学】计算机科学与自动化——第三百零五篇 计算机系统中的各类运算操作01

编号类型领域运算操作运算类型算法算法的详细设计及数学分析参数列表及参数的数值设计应用场景 (100+条)集合运算​1集合运算关系代数并集 (Union)集合运算归并排序去重合并两个集合,去除重复元素。时间复杂度 O(n+m),n,m为两集合大小。输入:集合A, B。输出:A∪B。数据集成、多表结果合并、去重后的全量数据提取。2集合运算关系代数交集 (Intersection)集合运算哈希交集找出同时属于两个集合的元素。平均时间复杂度 O(min(n,m)),最坏 O(n*m)。输入:集合A, B。输出:A∩

weixin_49199313的博客 1389

【算法笔记】反转二叉树

反转二叉树问题 翻转一棵二叉树。 示例: 输入: 输出: 问题分析

weiwai的博客 3608

钉钉Java面经及参考答案

TCP 三次握手建立连接的核心目标是双向确认双方发送、接收能力,同步通信序列号,协商初始窗口大小,防止历史过期连接报文干扰新连接。第一次握手,客户端主动向服务端发送 SYN 报文,携带客户端随机生成的初始序列号 ISN,客户端状态变更为 SYN_SENT,目的是告知服务端客户端具备发送数据的能力。第二次握手,服务端收到 SYN 报文后,回复 SYN+ACK 报文,其中 ACK 确认号为客户端 ISN+1,同时携带服务端自身随机初始序列号,服务端进入 SYN_RCVD 状态,代表服务端确认收到客户端报文,且自

大模型大数据攻城狮的专栏 238

一文详解反转二叉树

反转二叉树

abc123mma的博客 1226

【信息科学与工程学】计算机科学与自动化——第一百五十五篇 缓存系统设计02

编号176-190共15个条目,覆盖了缓存互连网络(环形/交叉开关)、硅光互连、散热设计、3D封装TSV、信号完整性、冗余设计、老化补偿、电磁兼容、时钟分布、JTAG测试、安全硬件、调试探针、容错路由、体偏置、共振时钟。:编号161-175共15个条目,聚焦于缓存硬件设计与配置,涵盖了MESI协议、多级TLB、分支预测BTB/BHT、自适应预取引擎、ECC纠错汉明码、路分区硬件、非暂时性存储旁路、缓存冲刷指令、缓存锁定、压缩硬件、嗅探过滤器、虚拟化EPT、QoS限速、内置自测BIST、电源管理DVFS。

weixin_49199313的博客 177

FastBuilding 3DMAX插件:批量生成配楼,让建筑可视化告别手动重复建模

在建筑可视化与城市规划项目中,配楼群是营造城市氛围和方案完整度的关键,但几十上百栋配楼的建模往往成为工期瓶颈。传统复制粘贴或BOX贴图方式无法兼顾真实感与效率。FastBuilding作为一款3DMAX插件,通过参数化生成逻辑,将配楼制作转化为可调控的流水线:设定层高、面宽、窗户密度等参数,即可在视口内实时生成带完整外立面细节的实体模型;支持点选拉框和样条线批量生成两种模式,配合随机种子可快速产出丰富而不失协调的建筑群。该插件不仅面数控制合理,生成模型仍可继续编辑,尤其适合住宅区鸟瞰、规划投标及远景天际线等

weixin_28520495的博客 251

【算法入门14】二叉树的镜像

核心考点:二叉树操作 操作给定的二叉树,将其变换为源二叉树的镜像。 解析: 要将一棵二叉树变化为自身的镜像,只需交换该二叉树每一个结点的左右子树即可。 例如,上述二叉树我们交换根结点的左右子树后源二叉树会发生如下变化。 再继续交换下一层结点的左右子树后,便可得到源二叉树镜像后的二叉树。 但实际上我们还会交换叶子结点的左右子树,只不过叶子结点的左右子树都为空树交换后二叉树无变化。 二叉树都是递归定义的,所以递归操作是比较常见的做法。 /* struct TreeNode { int val; s

2021dragon的博客 3556

ubuntu18.04安装xenomai3.1(百分百成功版)

ubuntu18.04安装xenomai3.1(百分百成功版),保姆级教学!!!

h542812556sdu的博客 2065

嵌软编程刷题记录

并且活动主持人需要全程参与活动,换句话说,一个主持人参与了第 i 个活动,那么该主持人在 (有 n 个活动即将举办,每个活动都有开始时间与活动的结束时间,第 i 个活动的开始时间是。求为了成功举办这 n 个活动,最少需要多少名主持人。2. 任意两个相邻的孩子之间,得分较多的孩子必须拿多一些糖果。复杂度要求:时间复杂度O(nlogn) ,空间复杂度 O(n)要求: 时间复杂度为O(n) 空间复杂度为 O(n),举办某个活动就需要为该活动准备一个活动主持人。输入:2,[[1,2],[2,3]]

2302_79514441的博客 370

Crossbar RRAM技术解析:从1TnR架构到存储革命

非易失性存储器(NVM)是数据存储的核心技术,其原理基于物理状态的稳定改变以实现数据持久化。阻变存储器(RRAM)作为一种新兴NVM,利用导电细丝在介质层中的形成与断裂实现数据存储,具有高速、低功耗和结构简单的优势。在工程实践中,RRAM面临潜行路径电流等挑战,而Crossbar提出的1TnR架构通过引入共享晶体管有效解决了这一问题,在保证性能的同时提升了集成密度。该技术与CMOS工艺兼容,支持后端集成与多层堆叠,为高密度存储和嵌入式应用提供了新的解决方案。结合当前行业对高能效、高密度存储的需求,RRAM在

weixin_42523104的博客 321

#基于原生JS的交互式代码高亮编辑器实现教程

本文介绍了一个轻量级交互式代码高亮编辑器的实现方案。该编辑器采用原生JavaScript开发,支持语法高亮、行号显示、主题切换等核心功能,适合嵌入博客、文档等场景使用。 项目技术栈包括HTML5/CSS3/JavaScript,使用Prism.js实现语法高亮,prettier提供代码格式化功能。编辑器界面分三个区域:顶部工具栏(语言选择/主题切换)、中间编辑区(行号+代码)、底部状态栏(语言/字符数)。 核心功能实现包括:通过contenteditable属性创建可编辑区域,Flex布局实现行号与代码同步

qq_42386733的博客 1036

数据结构与算法Python版:从入门到刷题通关实战手册

数据结构与算法是计算机科学的核心基础,也是软件工程师面试与工程实践的必备技能。无论是线性表、二叉树还是排序算法,其本质都是对数据组织方式与计算逻辑的抽象设计。Python凭借简洁的语法和内置的容器类型,让学习者能将更多精力聚焦于算法思想本身,而不被指针和内存管理等底层机制所困扰。从数组、链表到栈与队列,从树的遍历到快速排序、归并排序,再到KMP字符串匹配与图论搜索,每一个知识点都对应着真实场景中的性能优化与问题求解需求。掌握这些基础,不仅能帮助应对期末考核,更能为LeetCode刷题和实际项目开发奠定扎实的

weixin_30595035的博客 350

从HSPICE到Spectre:手把手教你搞定不同SPICE仿真器的网表转换(附避坑指南)

本文详细介绍了从HSPICE到Spectre的SPICE仿真器网表转换方法,包括核心语法差异、分步转换流程和常见问题排查。通过实战案例和避坑指南,帮助工程师高效解决不同SPICE仿真器间的兼容性问题,提升集成电路设计效率。

weixin_29745609的博客 368

每周技术面试高频题汇总:大厂面试官到底在考什么?完整实战指南

大家好,又到了每周的面试复盘时间。。现在的面试官更喜欢把你扔进一个具体的“场景”里,看你怎么思考、怎么权衡(Trade-off)。基于过去一周 优快云、掘金、LeetCode 等社区的热议内容,我为大家精选了,涵盖算法、系统设计、数据库和网络四大领域。咱们不整那些虚的,直接上干货,看看这些题目背后的考察点和解题思路。

热爱技术与前沿创新,深耕科技领域,在科创中精进自我;探索技术乐趣,分享技术干货与成长心得,以技术为伴,热爱生活,在科创与生活中双向成长。 482

【超详细】安装了anaconda后,Ubuntu18+COLMAP配置疯狂踩坑踩至魔怔的记录

本博客收集了博主在Ubuntu18系统中编译COLMAP所遇到的困难,提供了解决方法,也收集了目前网上大多数的坑,除此之外,也为Ubuntu18系统下COLMAP的安装提供了一种新的路径。

Stay_Foo_lish的博客 3511

基于深度学习的大豆病害检测识别系统:YOLOv10 + UI界面 + 数据集

YOLOv10是一种高效的目标检测算法,能够在保持高精度的同时,提供较快的检测速度。YOLOv10使用了改进的卷积神经网络架构,并在多个计算机视觉任务中表现出色。在本项目中,我们将使用YOLOv10进行大豆病害的检测和分类。本系统利用YOLOv10算法,实现了大豆病害的实时检测和分类。通过结合深度学习和图像处理技术,可以帮助农业领域的专业人员更加高效地识别和诊断大豆病害,提高农作物的生产力与质量。

YOLO 700

山水观心:从零构建嵌入式RTOS内核的架构与实战

嵌入式操作系统是物联网与智能硬件的核心基础,理解其内核源码与设计原理是开发者从裸机编程迈向RTOS的关键一步。本文以“山水观心”嵌入式内核项目为例,深入拆解其分层架构与设计哲学,展示如何基于C语言和Cortex-M平台从零构建一个轻量级实时操作系统。通过分析任务控制块、位图调度、优先级继承和栈溢出检测等实现细节,揭示内核背后的技术取舍。同时,结合嵌入式学习路线与嵌入式架构设计实战经验,提供实用的工程实践建议,帮助读者在嵌入式面试及竞赛中展现系统设计能力。无论你是初学者还是开发者,都能从中获得从“跑通代码”到

weixin_34109408的博客 341

linux系统中实现智能家居的基本方法

使用QT开发智能家居中的一个物联应用,通过云服务器远程控制设备与设备进行通信。在生活中,可以使用WIFI智能插座控制电器开关,比如远程开启热水器,远程打开空调,窗帘等等。包括:WIFI联网,注册到云服务器上,编写QT UI通过网络来与云服务器通信,然后再下发指令到这个连网的设备。硬件说明:需要有一个串口转WIFI模块,另外需要加上一个USB-TTL模块,外加一根T口USB连接线,可接入PC电脑调试。

嵌入式技术开发 2608

JZ27 二叉树的镜像

题目: 操作给定的二叉树,将其变换为源二叉树的镜像。 数据范围:二叉树的节点数0 \le n \le 10000≤n≤1000, 二叉树每个节点的值0\le val \le 10000≤val≤1000 要求:空间复杂度O(n)O(n)。本题也有原地操作,即空间复杂度O(1)O(1)的解法,时间复杂度O(n)O(n) 比如: 源二叉树 镜像二叉树 我的结果: 借助了堆栈。 /** * struct TreeNode { * int val; *...

qq_42082542的博客 1700

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

二叉树的翻转(镜像)

赋给根节点的左子树的根结点也就是pRoot->left,同时递归调用Mirror()将右子树的所有子树都进行交换,最后将pr存储的左子树的根节点赋给右子树的根节点也就是pRoot->right,到这里整颗树交换就已经完成了。,pr用来临时储存左子树根节点的地址,于此同时递归调用Mirror函数将其左子树的左右子树进行交换,将交换后的数的根节点返回。函数来翻转当前节点的右子树,并将返回的新的根节点(右子树的镜像)赋值给当前节点的左子指针。: 在完成当前节点的左右子树交换后,返回当前节点作为新的子树的根节点。

chaoxi6888的博客 1748

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

226. 反转二叉树(递归、迭代、广度优先遍历三种方法)

226. 反转二叉树 题目描述:给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。 解答: 想要翻转二叉树,其实就把每一个节点的左右孩子交换一下就可以了。关键在于遍历顺序,前中后序、层序应该选哪一种遍历顺序?遍历的过程中去翻转每一个节点的左右孩子就可以达到整体翻转的效果。 前序、后序、层序都比较易于实现,但是只有中序有点麻烦。 法一:采用递归法 之前有写过递归法实现前中后序遍历:二叉树的递归遍历_清榎的博客-优快云博客...

清榎的博客 1058

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

上一篇: C语言处理HTTP分块响应的底层逻辑(深度剖析TCP流与chunk边界分离)
下一篇: 揭秘Django bulk_create慢如蜗牛的原因:如何实现千条数据秒级插入
simcode
博客等级 码龄14年 154粉丝 2026原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值