本篇接着《LeetCode刷題總結-樹篇(上)》,講解有關樹的類型相關考點的習題,本期共收錄17道題,1道簡單題,10道中等題,6道困難題。
在LeetCode題庫中,考察到的不同種類的樹有七種,分別是二叉搜索樹、平衡二叉樹、滿二叉樹、完全二叉樹、線段樹、字典樹和樹狀數組。每一種類型的樹,有着不同的特性以及對應的考察重點。考察重點可參考下圖,下文按照樹的類型分別划分了一個目錄章節,並給出了對應的經典習題。
1 二叉樹搜索樹
基本定義:又稱二叉查找樹,二叉排序樹。若它的左子樹不空,則左子樹上所有結點的值均小於它的根結點的值;若它的右子樹不空,則右子樹上所有結點的值均大於它的根結點的值; 它的左、右子樹也分別為二叉搜索樹。參考示例圖如下(圖片來源):
考察重點:二叉搜索樹的創建問題、刪除二叉樹的指定節點、修改二叉樹節點的值、添加節點。
由於二搜索樹自身的特殊性質,可知插入和查找具體節點的時間復雜度為O(logn)。另外,需要謹記應用中序遍歷二叉搜索樹得到的序列為升序序列。對於添加、修改二叉樹的節點問題,中序遍歷的思想一般能夠提供較好的解答思路。
本部分收錄的習題(下面出現的數字為對應題目在LeetCode題庫中的序號),具體如下:
95.不同的二叉搜索樹 II,難度:中等 (考察搜索二叉樹的創建問題)
99.恢復二叉搜索樹,難度:困難 (考察搜索二叉樹修改節點的問題)
450.刪除二叉搜索樹中的節點,難度:中等(考察搜索二叉樹節點刪除問題)
701.二叉搜索樹中的插入,難度:中等(考察搜索二叉樹節點的插入問題)
對於上述四類考點,應用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; } }
2 平衡二叉樹
基本定義:它是一棵空樹或它的左右兩個子樹的高度差的絕對值不超過1,並且左右兩個子樹都是一棵平衡二叉樹。參考示例圖如下(圖片來源)
考察重點:給定一棵二叉樹,檢測該樹是否為平衡二叉樹。即考察我們遞歸遍歷樹的每個節點,檢測每個節點對應的左右子樹的高度差是否不大於1。
本部分收錄的習題:
3 滿二叉樹
基本定義:每個結點恰好有 0 或 2 個子結點。
考察重點:給定若干個元素,求能夠組成的不同滿二叉樹的個數。
本部分收錄的習題:
4 完全二叉樹
基本定義:完全二叉樹從根結點到倒數第二層滿足完美二叉樹,最后一層可以不完全填充,其葉子結點都靠左對齊。(附完美二叉樹定義:一個深度為k(>=-1)且有2^(k+1) - 1個結點的二叉樹稱為完美二叉樹。)參考示例圖如下(圖片來源):
考察重點:統計給定樹的節點個數、創建完全二叉樹以及檢測給定樹是否為完成二叉樹。
本部分收錄的習題:
222.完全二叉樹的節點個數,難度:中等(考察統計節點個數)
919.完全二叉樹插入器,難度:中等(考察創建完全二叉樹)
958.二叉樹的完全性檢驗,難度:中等(考察檢測是否為完全二叉樹)
5 線段樹
基本定義:線段樹是一種二叉搜索樹,與區間樹相似,它將一個區間划分成一些單元區間,每個單元區間對應線段樹中的一個葉結點。參考示例圖如下(圖片來源):
實際應用:使用線段樹可以快速的查找某一個節點在若干條線段中出現的次數,時間復雜度為O(logN)。
考察重點:給定問題,靈活轉換為線段樹求解。
應用Java語言創建線段樹時,可以借助內置的TreeSet和TreeMap數據結構。TreeSet是HashSet的升級版,TreeMap則是HashMap的升級版
本部分收錄的習題:
715. Range模塊,難度:困難(可以采用TreeSet構建線段樹,需要熟悉TreeSet在Java中相關接口的用法)
732.我的日程安排表III ,難度:困難 (可以采用TreeMap構建模擬化線段樹,需要熟悉TreeMap在Java中相關接口的用法)
850.矩形面積II,難度:困難(考察定義線段樹的標准解法)
6 字典樹
基本定義(百度百科):又稱單詞查找樹、前綴樹、Trie樹,是一種樹形結構,是一種哈希樹的變種。典型應用是用於統計,排序和保存大量的字符串(但不僅限於字符串),所以經常被搜索引擎系統用於文本詞頻統計。它的優點是:利用字符串的公共前綴來減少查詢時間,最大限度地減少無謂的字符串比較,查詢效率比哈希樹高。參考示例圖如下(圖片來源):
考察重點:創建字典樹、單詞搜索。
本部分收錄的習題:
208.實現Trie(前綴樹),難度:中等(考察創建字典樹)
212.單詞搜索II,難度:困難(考察單詞搜索)
648.單詞替換,難度:中等(考察單詞搜索)
7 樹狀數組
基本定義(百度百科):是一個查詢和修改復雜度都為log(n)的數據結構。主要用於查詢任意兩位之間的所有元素之和,但是每次只能修改一個元素的值;經過簡單修改可以在log(n)的復雜度下進行范圍修改,但是這時只能查詢其中一個元素的值(如果加入多個輔助數組則可以實現區間修改與區間查詢)。參考示例圖如下(圖片來源):
考察重點:構建樹狀數組。
本部分收錄的習題: