LeetCode刷題總結-樹篇(中)

       本篇接着《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。

本部分收錄的習題:

110.平衡二叉樹,難度:簡單

3 滿二叉樹

基本定義:每個結點恰好有 0 或 2 個子結點。

考察重點:給定若干個元素,求能夠組成的不同滿二叉樹的個數。

本部分收錄的習題:

894.所有可能的滿二叉樹,難度:中等

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)的複雜度下進行範圍修改,但是這時只能查詢其中一個元素的值(如果加入多個輔助數組則可以實現區間修改與區間查詢)。參考示例圖如下(圖片來源):

考察重點:構建樹狀數組。

本部分收錄的習題:

307.區域和檢索-數組可修改,難度:中等

315.計算右側小於當前元素的個數,難度:困難

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章