《劍指offer》-數據結構篇-樹

題目

  1. 重建二叉樹

  2. 樹的子結構

  3. 二叉樹的鏡像

  4. 從上往下打印二叉樹(層序遍歷)

  5. 把二叉樹打印成多行

  6. 按之字形順序打印二叉樹

  7. 二叉搜索樹的第k個結點(中序遍歷)

  8. 二叉搜索樹的后序遍歷序列(后序遍歷)

  9. 二叉樹中和為某一值的路徑

  10. 二叉樹的深度

  11. 平衡二叉樹

  12. 二叉樹的下一個結點

  13. 對稱的二叉樹

  14. 序列化二叉樹

代碼實現

重建二叉樹

題目描述:輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建出該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中都不含重復的數字。例如輸入前序遍歷序列{1,2,4,7,3,5,6,8}和中序遍歷序列{4,7,2,1,5,3,8,6},則重建二叉樹并返回。

思路:前序遍歷的第一個結點是根節點,據此和中序遍歷序列可以找到根節點的左子樹、右子樹包含的結點,返回的結果是樹的層序遍歷的結果{1,2,3,4,5,6,7,8}。典型題目,注意迭代的pre和tin的取值范圍。

class TreeNode:def __init__(self, x):self.val = xself.left = Noneself.right = None
class Solution:# 返回構造的TreeNode根節點def reConstructBinaryTree(self, pre, tin):# write code hereif len(pre)==0:return Noneroot=TreeNode(pre[0])TinIndex=tin.index(pre[0])root.left=self.reConstructBinaryTree(pre[1:TinIndex+1], tin[0:TinIndex])root.right=self.reConstructBinaryTree(pre[TinIndex+1:], tin[TinIndex+1:])return root

樹的子結構

題目描述:輸入兩棵二叉樹A,B,判斷B是不是A的子結構。(ps:我們約定空樹不是任意一個樹的子結構)

思路:依次判斷A與B的left、right,判斷pRoot2是否是pRoot1的子結構。

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:def HasSubtree(self, pRoot1, pRoot2):# write code here#這里認為pRoot1和pRoot2都為空時,沒法判斷子結構結果,認為比較的結果是False#if not pRoot1 and not pRoot2:#    return Trueif not pRoot1 or not pRoot2:return Falsereturn self.is_subtree(pRoot1, pRoot2) or self.HasSubtree(pRoot1.left, pRoot2) or self.HasSubtree(pRoot1.right, pRoot2)def is_subtree(self, A, B):if not B:return Trueif not A or A.val != B.val:return Falsereturn self.is_subtree(A.left,B.left) and self.is_subtree(A.right, B.right)

二叉樹的鏡像

題目描述:操作給定的二叉樹,將其變換為源二叉樹的鏡像。

思路:二叉樹每一層的結點進行左右交換,看得到的二叉樹的結點數值是否一致。

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:def Mirror(self, root):# write code hereif not root:return None   left, right = root.left, root.rightroot.left = rightroot.right = leftself.Mirror(root.left)self.Mirror(root.right)return root

從上往下打印二叉樹(層序遍歷)

題目描述:從上往下打印出二叉樹的每個節點,同層節點從左至右打印。

思路:從左至右添加每一層的結點。

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:# 返回從上到下每個節點值列表def PrintFromTopToBottom(self, root):# write code hereret = [] if root == None:return retbfs = [root]while(bfs):tbfs = []for node in bfs:ret.append(node.val)if node.left:tbfs.append(node.left)if node.right:tbfs.append(node.right)bfs = tbfsreturn ret

把二叉樹打印成多行

題目描述:從上到下按層打印二叉樹,同一層結點從左至右輸出。每一層輸出一行。

思路:注意和第13題的區別:這里是每一層輸出一行(用列表表示)。因而,輸出是一個嵌套列表。

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:def Print(self, pRoot):if not pRoot:return []nodeStack=[pRoot]result=[]while nodeStack:res = []nextStack=[]for i in nodeStack:res.append(i.val)if i.left:nextStack.append(i.left)if i.right:nextStack.append(i.right)nodeStack=nextStackresult.append(res)return result

按之字形順序打印二叉樹

題目描述:請實現一個函數按照之字形打印二叉樹,即第一行按照從左到右的順序打印,第二層按照從右至左的順序打印,第三行按照從左到右的順序打印,其他行以此類推。

思路:和第5題類似,但是這里需要對列表中的元素的位置序號進行“奇偶判斷”。注意:enumerate()結果的序號是從0開始的。

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:def Print(self, pRoot):if not pRoot:return []nodeStack=[pRoot]result=[]while nodeStack:res = []nextStack=[]for i in nodeStack:res.append(i.val)if i.left:nextStack.append(i.left)if i.right:nextStack.append(i.right)nodeStack=nextStackresult.append(res)returnResult=[]#上述代碼的運行結果是[[z1],[z2],...,[zn]],z1...zn表示對應的每一層的結點的值for i,v in enumerate(result):if i%2==0:returnResult.append(v)else:returnResult.append(v[::-1])return returnResult

二叉搜索樹的第k個結點(中序遍歷)

題目描述:給定一棵二叉搜索樹,請找出其中的第k小的結點。例如,(5,3,7,2,4,6,8)中,按結點數值大小順序第三小結點的值為4。

思路:利用中序遍歷實現。

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:# 中序遍歷找到第k個結點的數值def KthNode(self, pRoot, k):# write code hereif not pRoot: return Nonestack = []while pRoot or stack:while pRoot:stack.append(pRoot)pRoot = pRoot.leftpRoot = stack.pop()k -= 1if k == 0:return pRootpRoot = pRoot.right

二叉搜索樹的后序遍歷序列(后序遍歷)

題目描述:輸入一個整數數組,判斷該數組是不是某二叉搜索樹的后序遍歷的結果。如果是則輸出Yes,否則輸出No。假設輸入的數組的任意兩個數字都互不相同。

思路:根據二叉搜索樹性質:結點值大于結點的左結點的數值,小于結點的右結點的數值來實現。

# -*- coding:utf-8 -*-
class Solution:def VerifySquenceOfBST(self, sequence):# write code hereif len(sequence)==0:return Falseroot = sequence[-1]i = 0for node in sequence[:-1]:if node > root:breaki += 1for node in sequence[i:-1]:if node < root:return Falseleft = Trueif i > 1:left = self.VerifySquenceOfBST(sequence[:i])right = True#i < (len(sequence)-1)以確保是二叉搜索樹if (i < (len(sequence)-1))and left:right = self.VerifySquenceOfBST(sequence[i:-1])return left and right

二叉樹中和為某一值的路徑

題目描述:輸入一顆二叉樹的根節點和一個整數,打印出二叉樹中結點值的和為輸入整數的所有路徑。路徑定義為從樹的根結點開始往下一直到葉結點所經過的結點形成一條路徑。(注意: 在返回值的list中,數組長度大的數組靠前)

思路:遞歸,依據終止條件左結點=右結點=None且對應的根節點值是之前路徑的總和中差的最后一項值。在前序、中序和后序遍歷中只有前序遍歷是最先訪問根節點的,而且題中說在返回的list中數組長度大的數組在前,所以應該采用前序遍歷的方法。前序遍歷先訪問左子樹時,在每一個節點的根節點按照從左至右的順序進行訪問。將設定的值expectNumber與所經過的路徑中除去最后一個節點的值的和進行相減,然后將結果與遍歷的最后一個節點的值進行對比,如果相等的話則說明這條路徑是我們所想要的,然后記錄下來,返回ret。

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:# 返回二維列表,內部每個列表表示找到的路徑def FindPath(self, root, expectNumber):# write code hereret = []def dfs(root,sum_,tmp):if root:if root.left==None and root.right == None:if root.val == sum_:tmp.append(root.val)ret.append(tmp[:])else:tmp.append(root.val)dfs(root.left,sum_-root.val,tmp[:])dfs(root.right,sum_-root.val,tmp[:])dfs(root,expectNumber,[])return ret

二叉樹的深度

題目描述:輸入一棵二叉樹,求該樹的深度。從根結點到葉結點依次經過的結點(含根、葉結點)形成樹的一條路徑,最長路徑的長度為樹的深度。

思路:遞歸,求得根節點的左子樹和右子樹的深度,最后再加1。

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:def TreeDepth(self, pRoot):# write code hereif pRoot == None:return 0if pRoot.left == None and pRoot.right==None:return 1return max(self.TreeDepth(pRoot.left),self.TreeDepth(pRoot.right))+1

平衡二叉樹

題目描述:輸入一棵二叉樹,判斷該二叉樹是否是平衡二叉樹。

思路:平衡二叉樹的定義:是一棵空樹或它的左右兩個子樹的高度差的絕對值不超過1,并且左右兩個子樹都是一棵平衡二叉樹。根據定義來直接判斷。

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:def IsBalanced_Solution(self, pRoot):# write code hereif pRoot == None:return Trueif abs(self.TreeDepth(pRoot.left)-self.TreeDepth(pRoot.right)) > 1:return Falsereturn self.IsBalanced_Solution(pRoot.left) 
and self.IsBalanced_Solution(pRoot.right)def TreeDepth(self, pRoot):# write code hereif pRoot == None:return 0nLeft = self.TreeDepth(pRoot.left)nRight = self.TreeDepth(pRoot.right)return max(nLeft+1,nRight+1)#(nLeft+1 if nLeft > nRight else nRight +1)

二叉樹的下一個結點

題目描述:給定一個二叉樹和其中的一個結點,請找出中序遍歷順序的下一個結點并且返回。注意,樹中的結點不僅包含左右子結點,同時包含指向父結點的指針。

思路:判斷結點是左、右結點,然后按照中序遍歷的先左結點,后父結點,最后右結點的順序遍歷下一個結點。

class TreeNode:def __init__(self, x):self.val = xself.left = Noneself.right = None
class Solution:# 返回構造的TreeNode根節點def reConstructBinaryTree(self, pre, tin):# write code hereif len(pre)==0:return Noneroot=TreeNode(pre[0])TinIndex=tin.index(pre[0])root.left=self.reConstructBinaryTree(pre[1:TinIndex+1], tin[0:TinIndex])root.right=self.reConstructBinaryTree(pre[TinIndex+1:], tin[TinIndex+1:])return root

對稱的二叉樹

題目描述:請實現一個函數,用來判斷一顆二叉樹是不是對稱的。注意,如果一個二叉樹同此二叉樹的鏡像是同樣的,定義其為對稱的。

思路:遞歸判斷。注意和第12題的區別,這里不是生成一個鏡像的二叉樹,而是判斷已有的二叉樹是否是對稱的。

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None        
class Solution:def isSymmetrical(self, pRoot):# write code heredef is_same(p1,p2):if not p1 and not p2:return Trueif (p1 and p2) and p1.val==p2.val:return is_same(p1.left,p2.right) and is_same(p1.right,p2.left)return Falseif not pRoot:return Trueif pRoot.left and not pRoot.right:return Falseif not pRoot.left and pRoot.right:return Falsereturn is_same(pRoot.left,pRoot.right)

序列化二叉樹

題目描述:請實現兩個函數,分別用來序列化和反序列化二叉樹。二叉樹的序列化是指:把一棵二叉樹按照某種遍歷方式的結果以某種格式保存為字符串,從而使得內存中建立起來的二叉樹可以持久保存。序列化可以基于先序、中序、后序、層序的二叉樹遍歷方式來進行修改,序列化的結果是一個字符串,序列化時通過 某種符號表示空節點(#),以!表示一個結點值的結束(value!)。二叉樹的反序列化是指:根據某種遍歷順序得到的序列化字符串結果str,重構二叉樹。

思路:序列化的過程:按照層序遍歷的方式查找空節點,然后由“#”進行替換。反序列化的過程:查找不是“#”的結點值,然后添加,否則是None。

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:def __init__(self):self.index = -1def Serialize(self, root):# write code hereif root:return str(root.val) + ' ' +\self.Serialize(root.left) + \self.Serialize(root.right)else:return '# 'def Deserialize(self, s):# write code herel = s.split()self.index += 1if self.index >= len(s): return Noneif l[self.index] != '#':root = TreeNode(int(l[self.index]))root.left = self.Deserialize(s)root.right = self.Deserialize(s)else:return Nonereturn root

結尾

親愛的讀者朋友:感謝您在繁忙中駐足閱讀本期內容!您的到來是對我們最大的支持??

正如古語所言:"當局者迷,旁觀者清"。您獨到的見解與客觀評價,恰似一盞明燈💡,能幫助我們照亮內容盲區,讓未來的創作更加貼近您的需求。

若此文給您帶來啟發或收獲,不妨通過以下方式為彼此搭建一座橋梁: ? 點擊右上角【點贊】圖標,讓好內容被更多人看見 ? 滑動屏幕【收藏】本篇,便于隨時查閱回味 ? 在評論區留下您的真知灼見,讓我們共同碰撞思維的火花

我始終秉持匠心精神,以鍵盤為犁鏵深耕知識沃土💻,用每一次敲擊傳遞專業價值,不斷優化內容呈現形式,力求為您打造沉浸式的閱讀盛宴📚。

有任何疑問或建議?評論區就是我們的連心橋!您的每一條留言我都將認真研讀,并在24小時內回復解答📝。

愿我們攜手同行,在知識的雨林中茁壯成長🌳,共享思想綻放的甘甜果實。下期相遇時,期待看到您智慧的評論與閃亮的點贊身影?!

萬分感謝🙏🙏您的點贊👍👍、收藏?🌟、評論💬🗯?、關注??💚~


自我介紹:一線互聯網大廠資深算法研發(工作6年+),4年以上招聘面試官經驗(一二面面試官,面試候選人400+),深諳崗位專業知識、技能雷達圖,已累計輔導15+求職者順利入職大中型互聯網公司。熟練掌握大模型、NLP、搜索、推薦、數據挖掘算法和優化,提供面試輔導、專業知識入門到進階輔導等定制化需求等服務,助力您順利完成學習和求職之旅(有需要者可私信聯系)?

友友們,自己的知乎賬號為“快樂星球”,定期更新技術文章,敬請關注!????

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

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

相關文章

系統定時任務擴展開發指南

適用場景當系統內置定時任務類型無法滿足業務需求時&#xff0c;開發者可通過本教程快速掌握自定義定時任務的擴展方法。本指南以"定時檢測服務"為例&#xff0c;演示完整開發流程。我想添加一個定時任務 ,而這里沒有我需要的,我怎么來添加比如我想添加一個定時檢測用…

R語言簡介(附電子書資料)

概述 R語言是一種專為統計計算和數據分析設計的編程語言&#xff0c;自誕生以來&#xff0c;憑借其強大的統計分析能力和豐富的可視化功能&#xff0c;成為數據科學、統計學、機器學習等領域的重要工具。電子書資料&#xff1a;https://pan.quark.cn/s/23050825f2be 一、核心特…

關于前端的性能優化

性能優化主要涵蓋了以下四個方面: (tip:僅代表個人總結,如有不當,還希望看到的大佬多多指示) 減少網絡請求:合并文件、使用 CDN、啟用緩存。 優化資源加載:代碼分割、懶加載、圖片壓縮。 提升渲染性能:減少重繪回流、防抖節流、使用 Web Worker。 監控和迭代:定期使用工…

用 FFmpeg 把視頻輸出為圖片序列

用 FFmpeg 把視頻輸出為圖片序列 【推薦】輸出為PNG圖片序列&#xff08;無損&#xff09; mkdir "D:\Downloads\Recording" ffmpeg -i "C:\Users\33589\Videos\1.mp4" "D:\Downloads\Recording\Recording_%05d.png" 參數含義-i輸入視頻路徑&am…

【linux】高可用集群Keepalived

Keepalived簡介Keepalived 是一個基于 VRRP&#xff08;虛擬路由冗余協議&#xff09;的高可用解決方案&#xff0c;主要用于實現 Linux 服務器的負載均衡和故障轉移。它通過檢測服務器狀態并自動切換服務&#xff0c;確保系統在單點故障時仍能保持可用性Keeplived安裝啟用及配…

如何檢查服務器數據盤是否掛載成功?

在服務器配置過程中&#xff0c;確保數據盤正確掛載是非常重要的。如果數據盤未掛載成功&#xff0c;您可能無法訪問數據盤上的存儲空間。以下是檢查Linux服務器中數據盤是否掛載成功的詳細步驟&#xff0c;以及如何解決掛載問題。1. 檢查數據盤是否掛載成功1.1 使用 df -h 查看…

機器學習概述與 KNN 算法詳解

機器學習概述與 KNN 算法詳解引言在當今數字化時代&#xff0c;機器學習作為人工智能的核心技術&#xff0c;正深刻改變著我們的生活與工作方式。從日常的智能推薦到復雜的醫療診斷&#xff0c;機器學習技術的應用無處不在。本文將從機器學習的基本概念出發&#xff0c;闡述其核…

Java EE前端技術編程腳本語言JavaScript

-CoderOilStation(程序員編程助手科技股份責任有限公司)Java EE前端技術編程腳本語言JavaScript低代碼編程技術編寫少量的代碼規則。JavaScript腳本編程語言具體細節配置方式編程。前端技術過渡web3.0企業數字化。Java Service Page (JSP) JavaEE jdk6.5 發布企業應用版本Java研…

Docker+Kubernetes 實戰:數據模型的彈性伸縮與高可用部署方案

在生產環境中,數據模型的部署面臨雙重挑戰:一方面要應對流量波動(如電商大促期間預測接口調用量激增 10 倍),另一方面需保證服務零中斷(金融風控模型 downtime 每增加 1 分鐘可能導致數十萬元損失)。 本文基于實際項目經驗,詳細講解如何通過 Docker 容器化與 Kubernet…

vue3【組件封裝】頭像裁剪 S-avatar.vue

最終效果 技術要點 圖片裁剪 安裝依賴 vue-cropper npm install vue-croppernext專用于vue3 項目的圖片裁剪&#xff0c;詳細使用參考官方文檔 頁面使用 import "vue-cropper/dist/index.css"; import { VueCropper } from "vue-cropper";<vue-crop…

銅金礦數據分組優化系統設計與實現

銅金礦數據分組優化系統設計與實現 1. 項目概述 本項目旨在開發一個Python程序,用于根據給定的四組分組規則,優化包含金噸、干噸和銅單價等信息的Excel數據分組,以最大化總金額。系統需要處理的核心計算是每條數據的銅貨值,其公式為:結算銅金噸 銅單價 (價格系數 + 獎…

Python動態規劃:從基礎到高階優化的全面指南(3)

七、動態規劃性能優化實戰7.1 矩陣快速冪優化def matrix_mult(A, B):"""矩陣乘法"""n len(A)m len(B[0])p len(B)C [[0]*m for _ in range(n)]for i in range(n):for k in range(p):if A[i][k]:for j in range(m):C[i][j] A[i][k] * B[k][j…

海外紅人營銷的下一站:APP出海如何布局虛擬網紅與UGC生態?

在全球移動互聯網競爭日益激烈的今天&#xff0c;APP出海推廣的重心正從傳統流量采買和真人KOL合作&#xff0c;逐步向更具未來感的方向演進。虛擬網紅、AI生成內容以及用戶生成內容的融合&#xff0c;正為海外紅人營銷注入全新活力。這不僅是技術革新&#xff0c;更是用戶行為…

CentOS網卡未被托管解決記錄

VMWare掛起關機&#xff0c;又重啟后&#xff0c;出現一些很奇怪的問題。 我的幾臺CentOS的網卡都不見了&#xff0c;顯示網卡未被托管 [rootlocalhost ~]# nmcli device status DEVICE TYPE STATE CONNECTION virbr0 bridge 未托管 -- ens33 …

Node.js 中的內置模板path

1. path的作用&#xff1a;path 是 Node.js 中的一個內置模塊&#xff0c;用于處理文件和目錄路徑。它提供了一些工具來處理路徑字符串&#xff0c;確保路徑操作跨平臺兼容&#xff08;Windows 和 Unix 風格的路徑分隔符&#xff09;2.path的常用方法path.join()和數組的join方…

重生之我在暑假學習微服務第三天《Docker-上篇》

個人主頁&#xff1a;VON文章所屬專欄&#xff1a;微服務系列文章鏈接&#xff1a;重生之我在暑假學習微服務第一天《MybatisPlus-上篇》-CSDN博客重生之我在暑假學習微服務第二天《MybatisPlus-下篇》-CSDN博客時間&#xff1a;每天12點前準時更新 特別聲明&#xff1a;本篇文…

【硬件】LT3763中文手冊

目錄 1.簡介 1.1 特點 1.2 簡述 1.3 典型原理圖 1.4 絕對最大額定值 2.電氣特性 3.引腳功能 4.框圖 4.1 設計電感電流 4.2 電感選擇 4.3 開關MOSFET選擇 4.4 輸入電容選擇 4.5 輸出電容選擇 4.6 CBOOST電容選擇 4.7 INTVCC電容器選擇 4.8 Soft-Start 4.9 輸出電流…

【計算機科學與應用】基于多域變換的視頻水印嵌入算法研究

導讀&#xff1a; 為提升視頻水印在版權保護中的實際應用效果&#xff0c;本文提出一種基于多域變換的視頻水印嵌入算法。該算法結合離散小波變換(Discrete Wavelet Transform, DWT)與離散余弦變換(Discrete Cosine Transformation, DCT)&#xff0c;利用其在時頻域分析與能量…

Axios基本使用

介紹 Axios 是一個基于promise網絡請求庫&#xff0c;作用于node.js和瀏覽器中 特性 從瀏覽器創建 XMLHttpRequests從 node.js 創建 http 請求支持 Promise API攔截請求和響應轉換請求和響應數據取消請求自動轉換JSON數據客戶端支持防御XSRF 安裝 項目中 npm install axi…

【大模型LLM】梯度累積(Gradient Accumulation)原理詳解

梯度累積&#xff08;Gradient Accumulation&#xff09;原理詳解 梯度累積是一種在深度學習訓練中常用的技術&#xff0c;特別適用于顯存有限但希望使用較大批量大小&#xff08;batch size&#xff09;的情況。通過梯度累積&#xff0c;可以在不增加單個批次大小的情況下模擬…