LeetCode 題目 116:填充每個節點的下一個右側節點指針

作者介紹:10年大廠數據\經營分析經驗,現任字節跳動數據部門負責人。
會一些的技術:數據分析、算法、SQL、大數據相關、python,歡迎探討交流
歡迎加入社區:碼上找工作
作者專欄每日更新:
LeetCode解鎖1000題: 打怪升級之旅
python數據分析可視化:企業實戰案例
漫畫版算法詳解
python源碼解讀
程序員必備的數學知識與應用

題目描述

給定一個完美二叉樹,其所有葉子節點都在同一層,每個父節點都有兩個子節點。二叉樹的定義如下:

class Node:def __init__(self, val=0, left=None, right=None, next=None):self.val = valself.left = leftself.right = rightself.next = next

填充它的每個 next 指針,讓這個指針指向其下一個右側節點。如果找不到下一個右側節點,則將 next 指針設置為 None

初始狀態下,所有 next 指針都被設置為 None

方法一:層序遍歷(BFS)

解題步驟:
  1. 使用隊列進行層序遍歷。
  2. 對于每一層的節點,通過隊列的長度來確定節點的數量。
  3. 遍歷當前層的節點,將每個節點的 next 指向隊列中的下一個節點。
  4. 最后一個節點的 next 指向 None
Python 代碼示例
from collections import dequedef connect(root):"""使用層序遍歷來填充每個節點的下一個右側節點指針。參數:root (Node): 完美二叉樹的根節點。返回:Node: 修改后的樹的根節點。"""# 如果根節點為空,則直接返回Noneif not root:return None# 初始化隊列,并將根節點加入隊列queue = deque([root])# 當隊列不為空時,進行層序遍歷while queue:# 獲取當前層的節點數量size = len(queue)# 遍歷當前層的每個節點for i in range(size):# 從隊列中取出一個節點node = queue.popleft()# 如果不是當前層的最后一個節點,將當前節點的next指向隊列中的下一個節點if i < size - 1:node.next = queue[0]# 如果當前節點有左子節點,將左子節點加入隊列if node.left:queue.append(node.left)# 如果當前節點有右子節點,將右子節點加入隊列if node.right:queue.append(node.right)# 返回根節點return root

方法一利用層序遍歷(BFS)來填充每個節點的下一個右側節點指針,下面通過 ASCII 圖形來說明這個方法的工作過程。

考慮一個完美二叉樹如下所示:

        1/ \2   3/ \ / \4  5 6  7
算法圖解

我們使用隊列來按層級遍歷這棵樹,并設置每個節點的 next 指針。以下是各個步驟的圖解說明:

初始狀態
  1. 初始化隊列以包含根節點。
隊列: [1]
第一層處理
  1. 取出節點 1,發現它有左右子節點 2 和 3,將這兩個節點加入隊列。
隊列: [2, 3]
next指針連接: 1 -> None
  1. 設置節點 1 的 next 指向 None(因為它是第一層的唯一節點)。
第二層處理
  1. 取出節點 2,由于它不是隊列中的最后一個節點,設置 next 指向隊列中的下一個節點(節點 3)。同時將節點 2 的子節點 4 和 5 加入隊列。
隊列: [3, 4, 5]
next指針連接: 2 -> 3
  1. 取出節點 3,設置 next 指向 None(因為它是當前層的最后一個節點),將節點 3 的子節點 6 和 7 加入隊列。
隊列: [4, 5, 6, 7]
next指針連接: 3 -> None
第三層處理
  1. 處理節點 4, 5, 6, 7 類似,按順序設置 next 指針:
隊列: [5, 6, 7]
next指針連接: 4 -> 5
隊列: [6, 7]
next指針連接: 5 -> 6
隊列: [7]
next指針連接: 6 -> 7
隊列: []
next指針連接: 7 -> None

在每一步中,我們從隊列中移除一個節點,如果該節點不是當前層的最后一個節點,則將其 next 指針設置指向隊列中的下一個節點。這樣,每一層的節點都通過 next 指針連成一條鏈。當處理完當前層的所有節點后,隊列中就包含了下一層的所有節點,重復以上步驟直到隊列為空。這樣的遍歷確保了每個節點的 next 指針正確地指向了其右側的節點。

方法二:使用已建立的 next 指針

解題步驟:
  1. 從根節點開始,利用上一層的 next 指針來遍歷和鏈接當前層的節點。
  2. 對于每個節點,鏈接其左子節點到右子節點,右子節點到下一個節點的左子節點(如果存在)。
Python 代碼示例
def connect(root):"""利用已建立的 next 指針來填充每個節點的下一個右側節點指針。參數:root (Node): 完美二叉樹的根節點。返回:Node: 修改后的樹的根節點。"""# 如果根節點為空,則直接返回Noneif not root:return None# 初始化leftmost指針,這個指針始終指向每一層的最左側節點leftmost = root# 當左側節點存在時,繼續處理下一層while leftmost.left:# 使用head指針遍歷當前層的節點,head初始指向當前層的最左側節點head = leftmostwhile head:# 將當前節點的左子節點的next指向右子節點head.left.next = head.right# 如果當前節點的next不為空,將右子節點的next指向當前節點next的左子節點if head.next:head.right.next = head.next.left# 移動到當前層的下一個節點head = head.next# 移動到下一層的最左側節點leftmost = leftmost.left# 返回根節點return root

方法三:遞歸法

解題步驟:
  1. 遞歸地連接每個節點的左子節點到其右子節點。
  2. 連接相鄰子樹的右子節點到左子節點。
Python 代碼示例
def connect(root):if not root or not root.left:return rootroot.left.next = root.rightif root.next:root.right.next = root.next.leftconnect(root.left)connect(root.right)return root

方法四:使用額外的節點追蹤下一層的開始

解題步驟:
  1. 使用一個額外的節點 dummy 來追蹤每一層的開始。
  2. 通過一個循環連接同一層的所有節點。
Python 代碼示例
def connect(root):if not root:return Nonecurrent = rootwhile current:dummy = Node(0)tail = dummywhile current:if current.left:tail.next = current.lefttail = tail.nextif current.right:tail.next = current.righttail = tail.nextcurrent = current.nextcurrent = dummy.nextreturn root

方法五:迭代優化

解題步驟:
  1. 類似于方法二,但使用迭代而非遞歸。
  2. 遍歷每一層,連接相應的節點。
Python 代碼示例
def connect(root):if not root:return Nonenode = rootwhile node and node.left:next_level = node.leftwhile node:node.left.next = node.rightnode.right.next =node.next.left if node.next else Nonenode = node.nextnode = next_levelreturn root

算法分析

  • 時間復雜度:所有方法都需要遍歷每個節點,因此時間復雜度為 O(N),其中 N 是樹中的節點數。
  • 空間復雜度
    • 方法一:O(N),需要額外的隊列。
    • 方法二至五:O(1),只使用常數額外空間。

不同算法的優劣勢對比

  • 層序遍歷(方法一)直觀且易于理解,但需要額外的空間來存儲隊列。
  • 使用已建立的 next 指針(方法二)是空間復雜度最優的解法,適合空間敏感的應用。
  • 遞歸法(方法三)代碼簡潔,但在非尾遞歸的編譯器上可能導致棧溢出。
  • 使用額外節點(方法四)適合不熟悉指針操作的場景。
  • 迭代優化(方法五)提供了一個折中的解決方案,空間復雜度低,且較易于理解。

應用示例

這些方法可以用在需要層級遍歷但希望節約空間的場景,如實時數據處理、游戲編程中的場景管理,或任何需要快速訪問同一層級節點的數據結構設計中。

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

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

相關文章

C#上位機1ms級高精度定時任務

precisiontimer 安裝擴展包 添加引用 完整代碼 using PrecisionTiming;using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; us…

WinSCP軟件出錯:連接被意外關閉了

問題描述&#xff1a; WinSCP 登錄 M3568 的 linux系統&#xff0c;提示 列出’/home/root’的目錄項時出錯&#xff0c;連接被意外關閉 具體提示如下圖所示&#xff0c;列出’/home/root’的目錄項時出錯。 連接被意外關閉了 服務器發送命令的退出狀態255 原因及解決&#xf…

notepad++安裝 hex-editor插件

打開notepad 點擊插件 搜索 hex-editor,點擊右側 安裝install 安裝成功后&#xff0c;在已安裝插件中就有顯示了

spring boot參數驗證注解@NotNull、@NotBlank和@NotEmpty區別

目錄 前言說明舉例 前言 使用spring boot參數驗證是常常會使用NotNull、NotBlank和NotEmpty三個判斷是否不為空的注解&#xff0c;中文都有不能為空的意思&#xff0c;大部分使用者都傻傻分清它們之間到底有什么區別。今天就讓咱們來一起探索它們之間的不同吧。 說明 注解名…

等保測評安全物理環境測評講解

等保測評中的安全物理環境測評主要關注信息系統的物理安全保護措施&#xff0c;確保機房、設備和數據的物理安全。以下是安全物理環境測評的關鍵點講解&#xff1a; 1. **物理位置選擇**&#xff1a; - 機房應選擇在具有防震、防風和防雨能力的建筑內。 - 應避免設在建筑…

【數據庫】數據庫指令

一。數據庫打開 1.命令行 2.進入mysql mysql -uroot -p密碼 3.退出 exit&#xff1b; 二。針對數據庫的操作 1.創建數據庫&#xff08;有分號&#xff09; create database student; 2.使用數據庫 use student 3.刪除數據庫&#xff08;有分號&#xff09; drop database…

verilog基礎語法之數據類型

verilog基礎語法之數據類型 1、 wire類型2、 reg類型3、向量 Verilog最常用的數據類型有兩種&#xff1a;線網&#xff08;wire&#xff09;和寄存器&#xff08;reg&#xff09;。其中&#xff0c;wire 類型表示硬件單元之間的物理連線&#xff0c;reg用來表示存儲單元。 1、…

數據庫調優-數據庫優化

數據庫優化 如何發現復雜的SQL有問題&#xff1f; 一個個去explain嗎&#xff1f;你有沒有這樣的困惑&#xff0c;開發代碼運行順暢絲滑&#xff0c;上生產了卻卡的一逼&#xff1f; 哈哈&#xff0c;相信大家都會遇到這樣的問題&#xff01; sql 復制代碼 # 舉個栗子&…

4. 從感知機到神經網絡

目錄 1. 從感知機到神經網絡 2. 最簡單的神經網絡 3. 激活函數的引入 1. 從感知機到神經網絡 之前章節我們了解了感知機&#xff0c;感知機可以處理與門、非與門、或門、異或門等邏輯運算&#xff1b;不過在感知機中設定權重的工作是由人工來做的&#xff0c;而設定合適的&a…

【將Maven源改為國內阿里云鏡像源】

目錄 一、如何配置Maven鏡像源&#xff1f; 二、Idea中的Maven配置 ?三、項目與你本地倉庫和中央倉庫的聯系 一、如何配置Maven鏡像源&#xff1f; 1、打開你的Maven用戶設置文件(settings.xml)。默認情況下&#xff0c;該文件存在于你的用戶目錄下的.m2文件夾中。如果你沒…

小程序內使用web-view組件嵌套H5頁面,當H5頁面更換了內容后,小程序里的h5頁面不更新

這個問題是由于小程序緩存了H5的內容造成的&#xff0c;可以在H5鏈接后面拼接個參數&#xff0c;加上時間戳可做用于H5的版本號&#xff0c;這樣每次訪問都可以全新的鏈接展示內容避免緩存&#xff0c;代碼如下wxml&#xff1a; <view> <web-view src"{{urlpath…

Kafka 執行命令超時異常: Timed out waiting for a node assignment

Kafka 執行命令超時異常&#xff1a; Timed out waiting for a node assignment 問題描述&#xff1a; 搭建了一個kafka集群環境&#xff0c;在使用命令行查看已有topic時&#xff0c;報錯如下&#xff1a; [rootlocalhost bin]# kafka-topics.sh --list --bootstrap-server…

《機器學習by周志華》學習筆記-決策樹-01

本書中的「決策樹」有時指學習方法,有時指學得的樹。 1、基本流程 1.1、概念 基本流程,亦稱「判定樹」 決策樹(decision tree),是一種常見的機器學習方法。以二分類任務為例,我們希望從給定訓練數據集學得一個模型,用以對新樣例進行分離。 以二分類任務為例,可看作對…

一圖看懂 | 藍卓煤炭行業解決方案

煤炭是我國能源保障的“壓艙石,也是國民經濟中重要的支柱產業之一無論是發電、建材、造紙、冶金、化工等工業領域都離不開煤炭近年來&#xff0c;在“雙碳”及能源安全雙重背景下推動智能化技術與煤炭產業的融合發展提升煤礦安全生產能力的重要性與日俱增智慧礦山的建設已逐漸成…

CentOS 7安裝配置docker

CentOS 7、8安裝、配置docker 這里宿主機的型號選擇是centos7.9.2009的版本 1.宿主機關閉防火墻和selinux&#xff0c;配置ipv4 #設置SELinuxdisabled vim /etc/selinux/config SELinuxdisabled 查看防火墻狀態&#xff1a;firewall-cmd --state 關閉防火墻&#xff1a;syst…

selenium爬取TapTap評論

上一篇寫的beautifulsoup和request爬取出的結果有誤。首先&#xff0c;TapTap網頁以JS格式解析&#xff0c;且評論并沒有“下一頁”&#xff0c;而是每次加載到底部就要進行等待重新加載。我們需要做的&#xff0c;是模仿瀏覽器的行為&#xff0c;所以這里我們用Selenium的方式…

2024年數維杯B題完整代碼和思路論文講解與分析

2024數維杯數學建模完整代碼和成品論文已更新&#xff0c;獲取↓↓↓↓↓ https://www.yuque.com/u42168770/qv6z0d/bgic2nbxs2h41pvt?singleDoc# 2024數維杯數學建模B題45頁論文和代碼已完成&#xff0c;代碼為全部問題的代碼 論文包括摘要、問題重述、問題分析、模型假設、…

【項目實戰】使用Github pages、Hexo如何10分鐘內快速生成個人博客網站

文章目錄 一.準備工作1.安裝git2.安裝node安裝 cnpm 3.使用 GitHub 創建倉庫&#xff0c;并配置 GitHub Pages0.Github Pages是什么1. 在 GitHub 上創建一個新倉庫2. 創建您的靜態網站3. 啟用 GitHub Pages4. 等待構建完成5. 訪問您的網站 二. Hexo1.什么是Hexo2.安裝Hexo1. 安…

【MySQL】求和查詢,目標值int,但空數據時返回null的問題(Java)

問題分析 int selectDeviceMonthRepairCount(String deviceType, String month);<select id"selectDeviceMonthRepairCount" resultType"int">SELECT SUM(repair_count)FROM warranty_recordsWHERE device_type #{deviceType}AND nian_yue #{month…

【代碼筆記】高并發場景下問題解決思路

高并發指的是在單位時間內&#xff0c;瞬時流量激增&#xff0c;系統需要同時處理大量并行的請求或操作。這種情況通常出現在面向大量用戶或服務的分布式系統中&#xff0c;尤其是當用戶請求高度集中時&#xff0c;比如促銷活動、秒殺活動、注冊搶課、熱點事件、定時任務調度等…