本篇接着《LeetCode刷題總結-樹篇(上)》,講解有關樹的類型相關考點的習題,本期共收錄17道題,1道簡單題,10道中等題,6道困難題。html
在LeetCode題庫中,考察到的不一樣種類的樹有七種,分別是二叉搜索樹、平衡二叉樹、滿二叉樹、徹底二叉樹、線段樹、字典樹和樹狀數組。每一種類型的樹,有着不一樣的特性以及對應的考察重點。考察重點可參考下圖,下文按照樹的類型分別劃分了一個目錄章節,並給出了對應的經典習題。java
基本定義:又稱二叉查找樹,二叉排序樹。若它的左子樹不空,則左子樹上全部結點的值均小於它的根結點的值;若它的右子樹不空,則右子樹上全部結點的值均大於它的根結點的值; 它的左、右子樹也分別爲二叉搜索樹。參考示例圖以下(圖片來源):node
考察重點:二叉搜索樹的建立問題、刪除二叉樹的指定節點、修改二叉樹節點的值、添加節點。golang
因爲二搜索樹自身的特殊性質,可知插入和查找具體節點的時間複雜度爲O(logn)。另外,須要謹記應用中序遍歷二叉搜索樹獲得的序列爲升序序列。對於添加、修改二叉樹的節點問題,中序遍歷的思想通常可以提供較好的解答思路。數組
本部分收錄的習題(下面出現的數字爲對應題目在LeetCode題庫中的序號),具體以下:數據結構
95.不一樣的二叉搜索樹 II,難度:中等 (考察搜索二叉樹的建立問題)搜索引擎
99.恢復二叉搜索樹,難度:困難 (考察搜索二叉樹修改節點的問題)spa
450.刪除二叉搜索樹中的節點,難度:中等(考察搜索二叉樹節點刪除問題).net
701.二叉搜索樹中的插入,難度:中等(考察搜索二叉樹節點的插入問題)code
對於上述四類考點,應用Java實現刪除二叉搜索樹中節點時,因爲採用遞歸的解法,須要特別注意深拷貝和淺拷貝的問題。另外,對於刪除操做能夠採用地址覆蓋的操做來實現,此部分的操做代碼能夠做爲模板記住。下面具體給出題號爲450題目的描述及解答代碼。
題目描述:
解答代碼:
class Solution { public TreeNode deleteNode(TreeNode root, int key) { if (root == null) return null; if (key < root.val) { // 待刪除節點在左子樹中 root.left = deleteNode(root.left, key); return root; } else if (key > root.val) { // 待刪除節點在右子樹中 root.right = deleteNode(root.right, key); return root; } else { // key == root.val,root 爲待刪除節點 if (root.left == null) // 返回右子樹做爲新的根 return root.right; else if (root.right == null) // 返回左子樹做爲新的根 return root.left; else { // 左右子樹都存在,返回後繼節點(右子樹最左葉子)做爲新的根 TreeNode successor = min(root.right); successor.right = deleteMin(root.right); successor.left = root.left; return successor; } } } private TreeNode min(TreeNode node) { if (node.left == null) return node; return min(node.left); } private TreeNode deleteMin(TreeNode node) { if (node.left == null) return node.right; node.left = deleteMin(node.left); return node; } }
基本定義:它是一棵空樹或它的左右兩個子樹的高度差的絕對值不超過1,而且左右兩個子樹都是一棵平衡二叉樹。參考示例圖以下(圖片來源)
考察重點:給定一棵二叉樹,檢測該樹是否爲平衡二叉樹。即考察咱們遞歸遍歷樹的每一個節點,檢測每一個節點對應的左右子樹的高度差是否不大於1。
本部分收錄的習題:
基本定義:每一個結點剛好有 0 或 2 個子結點。
考察重點:給定若干個元素,求可以組成的不一樣滿二叉樹的個數。
本部分收錄的習題:
基本定義:徹底二叉樹從根結點到倒數第二層知足完美二叉樹,最後一層能夠不徹底填充,其葉子結點都靠左對齊。(附完美二叉樹定義:一個深度爲k(>=-1)且有2^(k+1) - 1個結點的二叉樹稱爲完美二叉樹。)參考示例圖以下(圖片來源):
考察重點:統計給定樹的節點個數、建立徹底二叉樹以及檢測給定樹是否爲完成二叉樹。
本部分收錄的習題:
222.徹底二叉樹的節點個數,難度:中等(考察統計節點個數)
919.徹底二叉樹插入器,難度:中等(考察建立徹底二叉樹)
958.二叉樹的徹底性檢驗,難度:中等(考察檢測是否爲徹底二叉樹)
基本定義:線段樹是一種二叉搜索樹,與區間樹類似,它將一個區間劃分紅一些單元區間,每一個單元區間對應線段樹中的一個葉結點。參考示例圖以下(圖片來源):
實際應用:使用線段樹能夠快速的查找某一個節點在若干條線段中出現的次數,時間複雜度爲O(logN)。
考察重點:給定問題,靈活轉換爲線段樹求解。
應用Java語言建立線段樹時,能夠藉助內置的TreeSet和TreeMap數據結構。TreeSet是HashSet的升級版,TreeMap則是HashMap的升級版
本部分收錄的習題:
715. Range模塊,難度:困難(能夠採用TreeSet構建線段樹,須要熟悉TreeSet在Java中相關接口的用法)
732.個人日程安排表III ,難度:困難 (能夠採用TreeMap構建模擬化線段樹,須要熟悉TreeMap在Java中相關接口的用法)
850.矩形面積II,難度:困難(考察定義線段樹的標準解法)
基本定義(百度百科):又稱單詞查找樹、前綴樹、Trie樹,是一種樹形結構,是一種哈希樹的變種。典型應用是用於統計,排序和保存大量的字符串(但不只限於字符串),因此常常被搜索引擎系統用於文本詞頻統計。它的優勢是:利用字符串的公共前綴來減小查詢時間,最大限度地減小無謂的字符串比較,查詢效率比哈希樹高。參考示例圖以下(圖片來源):
考察重點:建立字典樹、單詞搜索。
本部分收錄的習題:
208.實現Trie(前綴樹),難度:中等(考察建立字典樹)
212.單詞搜索II,難度:困難(考察單詞搜索)
648.單詞替換,難度:中等(考察單詞搜索)
基本定義(百度百科):是一個查詢和修改複雜度都爲log(n)的數據結構。主要用於查詢任意兩位之間的全部元素之和,可是每次只能修改一個元素的值;通過簡單修改能夠在log(n)的複雜度下進行範圍修改,可是這時只能查詢其中一個元素的值(若是加入多個輔助數組則能夠實現區間修改與區間查詢)。參考示例圖以下(圖片來源):
考察重點:構建樹狀數組。
本部分收錄的習題: