[從零開始面試算法] (11/100) LeetCode 226. 反轉二叉樹:遞歸的“鏡像”魔法

引言

歡迎來到本系列的第十一篇!在我們通過“最大深度”問題初步領略了樹的遞歸之美后,今天我們將面對一個更能體現遞歸“分治”思想的經典問題——LeetCode 226. 反轉二叉樹

這道題在面試界的地位非同凡響,它因 Homebrew 的作者 Max Howell 在 Google 面試時被這道題難住,并憤然發推吐槽而聞名于世。但這道題真的那么難嗎?

當你第一次看到這道題,你可能會發現它具有一種“鏡像”的對稱性,并且可以分解成更小的、相同的問題。這正是解決它的正確方向!但如何將這種直覺轉化為清晰、正確的代碼呢?

本文將帶你一起:

  1. 分析并完善關于“完全二叉樹”、“終止條件”等問題的初步想法。

  2. 深入理解遞歸如何像一個“自上而下的命令鏈”,優雅地完成整棵樹的反轉。

  3. 掌握解決這類樹結構修改問題的通用遞歸模板。


一、題目呈現

  • 題目編號:226. 反轉二叉樹

  • 題目難度:簡單

  • 題目鏈接:226. 反轉二叉樹 - 力扣 (LeetCode)

  • 題目描述

    給你一棵二叉樹的根節點?root?,翻轉這棵二叉樹,并返回其根節點。

  • 示例

    • 輸入:?root = [4,2,7,1,3,6,9]

    • 輸出:?[4,7,2,9,6,3,1]

    反轉前:

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

反轉后:

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

二、我的思考:遞歸直覺的打磨

這里完全采用你的筆記思路

看到這棵樹,我的第一反應是:這個問題可以拆分成更小的相同問題。比如,要反轉整棵以?4?為根的樹,似乎可以先反轉以?2?為根的左子樹,再反轉以?7?為根的右子樹,最后再做點什么。這種“分治”的感覺,讓我立刻想到了遞歸。

我的初步想法是:

  1. 終止條件:當遞歸到最左邊的葉子節點,它的?left?是?nullptr?時,就應該停止了。

  2. 核心操作:在某個節點,我需要交換它的?left?和?right?指針,這需要一個臨時變量來暫存。

但我很困惑:我應該按什么順序去遞歸呢?先一路遞歸到最左邊,再處理右邊嗎?那返回的順序好像不對。而且,函數最后應該返回什么?是節點的值?val?嗎?

你的思考過程非常棒!你已經抓住了遞歸交換這兩個核心要素。現在,我們來逐一打磨這些想法,掃清困惑。

  1. 關于終止條件:只考慮?left?為?nullptr?是不夠的。一個更通用、更安全的終止條件是:當遞歸遇到的當前節點?root?本身是?nullptr?時,就返回。因為我們不能對一個空節點做任何操作。

  2. 關于返回值:函數的簽名是?TreeNode* invertTree(TreeNode* root),它要求我們返回一個?TreeNode*?指針。我們的任務是修改樹的結構,并最終返回修改后整棵樹的根節點

  3. 關于遞歸順序:這正是本題的精髓!答案是,對于“反轉”這個操作,先處理當前節點,再遞歸子節點(前序遍歷)?的思路是最直觀的。


三、豁然開朗:遞歸的“自頂向下”反轉模型

讓我們把反轉過程想象成一個**“將軍下令”**的指揮鏈。

將軍(當前根節點?root)的任務只有兩件:

  1. 先行動:交換自己直接指揮的兩個師長(左子節點?left?和右子節點?right)的位置。

  2. 再下令:對換完位置的兩位師長分別說:“現在,你們各自去把手下的部隊(你們的子樹)也全部反轉一遍!”

這個命令會從最高級的將軍?root,一層層地傳遞下去,直到最底層的士兵(葉子節點)。當士兵接到命令,發現自己手下沒有兵(子節點為?nullptr)時,他什么也不做,直接報告“任務完成”。當所有士兵都報告完成后,整棵樹的“鏡像反轉”就完成了。

C++ 最優代碼與詳解

這個“將軍下令”的模型,可以被直接翻譯成極其簡潔的遞歸代碼。

完整代碼
/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode() : val(0), left(nullptr), right(nullptr) {}* };*/
class Solution {
public:TreeNode* invertTree(TreeNode* root) {// 1.if (root == nullptr) {return nullptr;}// --- 核心操作區 (前序遍歷位置) ---// 2.TreeNode* temp = root->left;root->left = root->right;root->right = temp;// 3.invertTree(root->left);invertTree(root->right);// 4.return root;}
};

代碼逐點解釋
  1. if (root == nullptr)
    遞歸的終止條件 (Base Case)。如果當前節點為空,它沒有子節點可以交換,直接返回?nullptr。這是遞歸能夠停止的保證。

  2. TreeNode* temp = ...;
    核心交換操作。我們先用一個臨時指針?temp?暫存左子節點的地址,然后將右子節點賦給左指針,最后將暫存的地址賦給右指針,完成了對當前節點?root?的直接子節點的交換。

  3. invertTree(root->left); invertTree(root->right);
    分治與遞歸。這是“將軍下令”的步驟。我們對已經交換過來的新左子樹和新右子樹,分別進行遞歸調用。我們完全信任這兩個遞歸調用能完美地反轉它們各自內部的所有結構。

  4. return root;
    返回結果。在完成了本層的交換和對子樹的遞歸反轉之后,當前?root?節點下的整棵子樹都已經完成了反轉。我們將這個?root?返回給它的上層調用。最終,最頂層的調用會返回整棵樹的新根節點(其實還是原來的那個根節點,但它的結構已經被改變了)。


四、總結與收獲

  • 復雜度分析:我們恰好訪問了樹中的每一個節點一次來執行交換操作。因此,時間復雜度為?O(n),其中 n 是節點的總數。遞歸調用棧的深度最壞情況下等于樹的高度,因此空間復雜度為?O(h)

  • 核心思想:對于樹這種具有天然遞歸結構的題目,分治思想是解決問題的金鑰匙。將一個大問題(反轉整棵樹)分解為三個小步驟:處理當前節點遞歸處理左子樹遞歸處理右子樹

  • 關鍵技巧:理解遞歸函數調用的本質。當你寫?invertTree(root->left)?時,你要在腦中形成一種“信任”——相信這個函數一定會返回一個已經完全反轉好的左子樹,而無需關心其內部細節。這種“定義與信任”是掌握遞歸的關鍵。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/95722.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/95722.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/95722.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Java設計模式之創建型—建造者模式

Java中最常用的設計模式-CSDN博客 “把對象的構造步驟拆成鏈式方法,調用者按需填參,最后一次性 build,避免構造函數爆炸。” 經典場景 參數多(>4 個)且大部分可選 需要不可變對象(final 字段&#xf…

網頁計時器,支持多計時器管理、數據分享、用戶數據同步、全屏展示等功能,可進行倒計時、正計時和顯示世界時鐘。

一個具有現代化 UI 和交互的計時器網頁應用,支持多計時器管理、數據分享、用戶數據同步、全屏展示等功能,可進行倒計時、正計時和顯示世界時鐘。它采用玻璃態設計和流暢動畫效果,提供極佳的視覺體驗。 特點: 支持多個計時器的創建…

紋理融合——用 TypeScript + Babylon.js 打造“可混合紋理序列”

我不想搞個一新的Shader,我就想用已有的材質(比如StandardMaterial和PBRMetallicRoughnessMaterial)實現紋理融合漸變等效果,于是我搞了一個TextureBlender。一、為什么重復造輪子?GPU 插值受限material.diffuseTextur…

【完整源碼+數據集+部署教程】公交車部件實例分割系統源碼和數據集:改進yolo11-fasternet

背景意義 隨著城市化進程的加快,公共交通系統的需求日益增加,公交車作為城市交通的重要組成部分,其運行效率和安全性直接影響到城市的交通狀況和居民的出行體驗。因此,公交車的維護和管理顯得尤為重要。在這一背景下,公…

【C++題解】關聯容器

關于set,map以及變種 |關聯容器| set&multiset | map&multimap |無序關聯容器| Unordered set&multiset | Unordered map&multimap | 建議先了解之后再配合練習 這次練習CCF真題比較多,也比較基礎,預計耗時不用這么久。 今天…

【智譜清言-GLM-4.5】StackCube-v1 任務訓練結果不穩定性的分析

1. Prompt 我是機器人RL方向的博士生正在學習ManiSkill,在學習時我嘗試使用相同命令訓練同一個任務,但是我發現最終的 success_once 指標并不是相同的,我感到十分焦慮, 我使用的命令如下: python sac.py --env_id&qu…

MySQL 8.0 主從復制原理分析與實戰

MySQL 8.0 主從復制原理分析與實戰半同步復制設計理念:復制狀態機——幾乎所有的分布式存儲都是這么復制數據的基于全局事務標識符(GTID)復制GTID工作原理多主模式多主模式部署示例課程目標: MySQL 復制(Replication&a…

[UT]記錄case中seq.start(sequencer)的位置變化帶來的執行行為的變化

現象: 代碼選擇打開57行,注釋掉60行執行,結果58行不會打印。 代碼選擇打開60行,注釋57行執行,結果58行正常打印。 sequence的執行需要時間!!! SV中代碼57行切換到60行的區別&#xf…

利用keytool實現https協議(生成自簽名證書)

利用keytool實現https協議(生成自簽名證書)什么是https協議?https(安全超文本傳輸協議)是 HTTP 的安全版本,通過 SSL/TLS 加密技術,在客戶端(如瀏覽器)和服務器之間建立加…

拆解 AI 大模型 “思考” 邏輯:從參數訓練到語義理解的核心鏈路

一、引言:揭開 AI 大模型 “思考” 的神秘面紗?日常生活中的 AI 大模型 “思考” 場景呈現(如 ChatGPT 對話、AI 寫作輔助、智能客服應答)?提出核心問題:看似具備 “思考” 能力的 AI 大模型,其背后的運作邏輯究竟是…

element plus 使用細節 (二)

接上一篇文章: element plus 使用細節 最近菜鳥忙于系統開發,都沒時間總結項目中使用的問題,幸好還是在空閑之余總結了一點(后續也會來補充),希望能給大家帶來幫助! 文章目錄table fixed 的 v…

【機器學習學習筆記】numpy基礎2

零基礎小白的 NumPy 入門指南如果你想用電競(打游戲)的思路理解編程:Python 是基礎操作鍵位,而 NumPy 就是 “英雄專屬技能包”—— 專門幫你搞定 “數值計算” 這類復雜任務,比如算游戲里的傷害公式、地圖坐標&#x…

從自動化到智能化:家具廠智能化產線需求與解決方案解析

伴隨著工業4.0浪潮和智能制造技術的成熟,家具行業正逐步從傳統的自動化生產邁向智能化生產。智能化產線的構建不僅可以提升生產效率,還能滿足個性化定制和柔性制造的需求。本文以某家具廠為例,詳細解析智能化產線的核心需求,并提出…

macOS下基于Qt/C++的OpenGL開發環境的搭建

系統配置 MacBook Pro 2015 Intel macOS 12Xcode 14 Qt開發環境搭建 Qt Creator的下載與安裝 在Qt官網的下載頁面上下載,即Download Qt Online Installer for macOS。下載完成就得到一個文件名類似于qt-online-installer-macOS-x64-x.y.z.dmg的安裝包。 下一步 …

當液態玻璃計劃遭遇反叛者:一場 iOS 26 界面的暗戰

引子 在硅谷的地下代碼俱樂部里,流傳著一個關于 “液態玻璃” 的傳說 —— 那是 Apple 秘密研發的界面改造計劃,如同電影《變臉》中那張能改變命運的面具,一旦啟用,所有 App 都將被迫換上流光溢彩的新面孔。 而今天,我…

探究Linux系統的SSL/TLS證書機制

一、SSL/TLS證書的基本概念 1.1 SSL/TLS協議簡介 SSL/TLS是一種加密協議,旨在為網絡通信提供機密性、完整性和身份驗證。它廣泛應用于HTTPS網站、電子郵件服務、VPN以及其他需要安全通信的場景。SSL(安全套接字層)是TLS(傳輸層安全…

python和java爬蟲優劣對比

Python和Java作為爬蟲開發的兩大主流語言,核心差異源于語法特性、生態工具鏈、性能表現的不同,其優勢與劣勢需結合具體場景(如開發效率、爬取規模、反爬復雜度)判斷。以下從 優勢、劣勢、適用場景 三個維度展開對比,幫…

Unity 槍械紅點瞄準器計算

今天突然別人問我紅點瞄準器在鏡子上如何計算,之前的吃雞項目做過不記得,今天寫個小用例整理下。 主體思想記得是目標位置到眼睛穿過紅點瞄準器獲取當前點的位置就可以。應該是這樣吧,:) 武器測試結構 首先整個結構&am…

題解 洛谷P13778 「o.OI R2」=+#-

文章目錄題解代碼居然沒有題解?我來寫一下我的抽象做法。 題解 手玩一下,隨便畫個他信心的折線圖,如下: 可以發現,如果我們知道終止節點,那么我們就可以知道中間有多少個上升長度。(因為它只能…

RTSP流端口占用詳解:TCP模式與UDP模式的對比

在音視頻傳輸協議中,RTSP(Real-Time Streaming Protocol,實時流傳輸協議)被廣泛用于點播、直播、監控等場景。開發者在實際部署或調試時,常常會遇到一個問題:一路 RTSP 流到底占用多少個端口? 這…