成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

LeetCode題解之二叉樹

開發 前端
聽名字還是比較好理解的,就是每個節點有兩個分叉的樹。但是又不要求一定有兩個節點,只要小于等于2個節點就可以。

前言

今天說說二叉樹。

首先看看什么是樹??。

如圖,這種有節點的結構就是樹。

樹 是n(n>=0)個結點的有限集

其中:

  • 每個元素叫做 節點
  • 上一節是下一節的 父節點,比如1是2的父節點
  • 最上面的節點,也就是沒有父節點的節點叫做 根節點,比如1
  • 同一個父節點的節點叫做 兄弟節點,比如2、3、4是兄弟節點
  • 沒有子節點的節點叫做 葉子節點

二叉樹

聽名字還是比較好理解的,就是每個節點有兩個分叉的樹。但是又不要求一定有兩個節點,只要小于等于2個節點就可以。

比如這種:

其中,可以看到綠色的樹每個節點都有左右兩個節點,這種二叉樹就叫做 滿二叉樹。

還有一種二叉樹叫做 完全二叉樹。

完全二叉樹: 對一顆具有n個結點的二叉樹按層編號,如果編號為i(1<=i<=n)的結點與同樣深度的滿二叉樹中編號為i的結點在二叉樹中位置完全相同,則這棵二叉樹稱為完全二叉樹。

啥意思呢,比如一個滿二叉樹,每個節點進行順序編號,如果去了一些節點,編號不會變化,那么就是完全二叉樹,比如:

這張圖中,綠色樹是滿二叉樹,當去掉7號節點,變成了黃色樹。

這顆黃色樹的序號相對于滿二叉樹的序號都能一一對應,所以這個黃色樹就是完全二叉樹。

如果去掉的是6號節點,變成紅色樹,這時候,紅色樹的節點就必須有所變化了,6消失后節點7必須變成節點6才正確。

所以這個紅色樹就不是完全二叉樹,因為它相對于滿二叉樹序號有所改變,已經對應不上了。

算法——平衡二叉樹

說了這么多,該來個題練練手了。

輸入一棵二叉樹的根節點,判斷該樹是不是平衡二叉樹。如果某二叉樹中任意節點的左右子樹的深度相差不超過1,那么它就是一棵平衡二叉樹。

示例 1: 給定二叉樹 [3,9,20,null,null,15,7]

  1.   3 
  2.  / \ 
  3. 9  20 
  4.   /  \ 
  5.  15   7 

返回 true 。

解析

題目給出了平衡二叉樹的概念,就是任意節點的左右子樹相差不超過1,就是平衡二叉樹。

那這個深度是啥呢?

深度就是根節點到當前節點經過的邊個數

層數就是當前節點在第幾層,跟節點為第一層,所以層數=深度+1

  1.  1       深度 0 ,層數 1 
  2.  / \ 
  3. 2  3      深度 1 ,層數 2 
  4.   /  \ 
  5.  4    5   深度 2 ,層數 3 

解法1

首先容易想到的就是把每個節點的深度都算出來,然后進行左右節點比較就能得出是不是平衡二叉樹。

那么節點的子樹深度怎么計算呢?

遞歸。當子節點為空就返回,否則每次增加一個單位深度。

  1. /** 
  2.  * Definition for a binary tree node. 
  3.  * public class TreeNode { 
  4.  *     int val; 
  5.  *     TreeNode left
  6.  *     TreeNode right
  7.  *     TreeNode(int x) { val = x; } 
  8.  * } 
  9.  */ 
  10.  
  11.     private int depth(TreeNode root) { 
  12.         if (root == nullreturn 0; 
  13.         return Math.max(depth(root.left), depth(root.right)) + 1; 
  14.     } 

深度搞定了,這題就好解了,即遍歷每個節點的左右深度,還是要 用到遞歸:

  1. class Solution { 
  2.     public boolean isBalanced(TreeNode root) { 
  3.         if (root == nullreturn true
  4.         return Math.abs(depth(root.left) - depth(root.right)) <= 1 && isBalanced(root.left) && isBalanced(root.right); 
  5.     } 
  6.  
  7.     private int depth(TreeNode root) { 
  8.         if (root == nullreturn 0; 
  9.         return Math.max(depth(root.left), depth(root.right)) + 1; 
  10.     } 

從根節點開始,計算每個左子樹深度和右子樹深度的差值,以及下面的每個節點的左子樹和右子樹深度,最終得出結果。

這種先處理節點,在處理左子樹,再處理右子樹 的遍歷方式叫做 前序遍歷或者先序遍歷。

時間復雜度

假設節點總數為n,層數為x,二叉樹為滿二叉樹。

時間復雜度計算可以通過 每層的時間復雜度 * 層數復雜度

每層的時間復雜度:

  • 第一層需要遍歷n次,第二層需要遍歷n-1次,第三層需要遍歷n-3次,所以每層的時間復雜度為O(n)

層數復雜度:

  • 第一層為1個節點,第二層為2個節點,第三層為4個節點,第x層為2的x-1次方。

借助公式:

  1. n >= 1+2+4+8+...+2^(x-2)+1 
  2. n <= 1+2+4+8+...+2^(L-2)+2^(L-1) 

計算:

  1. n >= 1+2+4+8+...+2^(x-2)+1 
  2. n >= (2^(x-1)-1) + 1  
  3. n >= 2^(x-1) 
  4. x <= log2n+1  

同理:

  1. x >= log2(n+1) 

所以一個接近平衡二叉樹的高度(層數)接近logn。

所以總的時間復雜度就是 O(nlogn)

空間復雜度

由于用到了遞歸,用到了堆棧幀,之前說過和最大遞歸深度成正比,所以空間復雜度為O(n)

解法2

還有沒有更好的解呢?

剛才我們用到的是先序遍歷,但是可以發現,每個節點都會計算一遍深度,會有大量重復計算,所以我們可以試試不重復的算法?比如直接后序遍歷。

后序遍歷:對于任意節點來說,先處理左子樹,再處理右子樹,最后再處理節點本身。

計算深度還是用到剛才的方法:

  1. private int depth(TreeNode root) { 
  2.       if (root == nullreturn 0; 
  3.       int left = recur(root.left); 
  4.       int right = recur(root.right); 
  5.       return Math.max(leftright) + 1; 
  6.   } 

如果能計算左子樹深度和右子樹深度,那么我們可以直接進行比較,如果發現某個節點的左子樹深度和右子樹深度相差大于1,那么就可以直接返回false了。

所以綜合能得出解法二:

  1. class Solution { 
  2.     public boolean isBalanced(TreeNode root) { 
  3.         return recur(root) != -1; 
  4.     } 
  5.  
  6.     private int recur(TreeNode root) { 
  7.         if (root == nullreturn 0; 
  8.         int left = recur(root.left); 
  9.         if(left == -1) return -1; 
  10.         int right = recur(root.right); 
  11.         if(right == -1) return -1; 
  12.         return Math.abs(left - right) < 2 ? Math.max(leftright) + 1 : -1; 
  13.     } 

時間復雜度

n為總節點,遍歷所有節點,所以時間復雜度為O(n)

空間復雜度

  1. O(n) 

參考

https://leetcode-cn.com/problems/ping-heng-er-cha-shu-lcof/

https://time.geekbang.org/column/article/67856

本文轉載自微信公眾號「碼上積木」,可以通過以下二維碼關注。轉載本文請聯系碼上積木公眾號。

 

責任編輯:武曉燕 來源: 碼上積木
相關推薦

2021-03-22 08:23:29

LeetCode二叉樹節點

2021-04-20 08:37:14

數據結構二叉樹

2021-04-19 07:47:42

數據結構二叉樹Tree

2020-04-27 07:05:58

二叉樹左子樹右子樹

2021-09-29 10:19:00

算法平衡二叉樹

2020-09-23 18:25:40

算法二叉樹多叉樹

2013-07-15 16:35:55

二叉樹迭代器

2021-04-28 20:12:27

數據結構創建

2021-08-27 11:36:44

二叉樹回溯節點

2023-05-08 15:57:16

二叉樹數據結構

2022-10-26 23:58:02

二叉樹數組算法

2021-05-06 17:46:30

二叉樹數據結構

2021-09-15 07:56:32

二叉樹層次遍歷

2021-12-17 14:26:58

二叉樹節點數量

2021-07-13 14:03:24

二叉樹滿二叉樹完全二叉樹

2021-10-12 09:25:11

二叉樹樹形結構

2018-03-15 08:31:57

二叉樹存儲結構

2022-10-12 23:25:17

二叉樹父節點根節點

2009-08-11 13:29:57

C#二叉樹遍歷

2020-12-22 08:56:51

JavaScript數據結構前端
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: av毛片在线免费观看 | 在线成人| 亚洲精品一区中文字幕乱码 | 日日骚av | 欧美一区二区三区视频 | 精品国产一二三区 | 日本a∨视频 | 精品蜜桃一区二区三区 | 久久精品一区 | 久久精品国产99国产精品 | 国产一区久久 | 国产视频导航 | 毛片免费观看视频 | 成人影院在线 | 欧美成人猛片aaaaaaa | 欧美一级淫片免费视频黄 | 亚洲视频网 | 99免费精品视频 | 粉嫩国产精品一区二区在线观看 | 国产精品亚洲一区 | 欧美日韩a | 国产精品亚洲综合 | 成人综合视频在线观看 | 日本在线一区二区三区 | 成人欧美一区二区三区色青冈 | 精品久久中文字幕 | 午夜在线观看视频 | 国产精品1区2区 | 成人在线亚洲 | 岛国视频 | 日本又色又爽又黄的大片 | 亚洲一区日韩 | 久久国产欧美日韩精品 | 91精品国模一区二区三区 | 欧美日韩一区在线 | 久久精品超碰 | 成人免费观看男女羞羞视频 | 激情的网站| av一级久久| 国产网站在线免费观看 | 一区二区三区国产好的精 |