国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Leetcode面試經典150題刷題記錄 —— 二叉搜索樹篇

這篇具有很好參考價值的文章主要介紹了Leetcode面試經典150題刷題記錄 —— 二叉搜索樹篇。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

Leetcod面試經典150題刷題記錄-系列
Leetcod面試經典150題刷題記錄——數組 / 字符串篇
Leetcod面試經典150題刷題記錄 —— 雙指針篇
Leetcod面試經典150題刷題記錄 —— 矩陣篇
Leetcod面試經典150題刷題記錄 —— 滑動窗口篇
Leetcod面試經典150題刷題記錄 —— 哈希表篇
Leetcod面試經典150題刷題記錄 —— 區(qū)間篇
Leetcod面試經典150題刷題記錄——棧篇
Leetcod面試經典150題刷題記錄——鏈表篇
Leetcod面試經典150題刷題記錄——二叉樹篇
Leetcod面試經典150題刷題記錄——二叉樹層次遍歷篇
本篇:Leetcod面試經典150題刷題記錄——二叉搜索樹篇

遇到二叉搜索樹(BST)的題目,一旦用了sort()直接掛掉面試,切記!

二叉搜索樹性質

二叉搜索樹的性質滿足:
(1)左節(jié)點 > root > 右節(jié)點 (局部性質)
(2)左子樹所有節(jié)點 > root > 右子樹所有節(jié)點 (全局性質,該性質包括局部性質,所以更重要)
相當部分程序員寫起上面的局部性質很容易,寫全局性質的判斷就容易犯病,不瞞你說,我也是。

1. 二叉搜索樹的最小絕對差

題目鏈接:二叉搜索樹的最小絕對差 - leetcode
題目描述:
給你一個二叉搜索樹的根節(jié)點 root ,返回 樹中任意兩不同節(jié)點值之間的最小差值 。差值是一個正數,其數值等于兩值之差的絕對值。
題目歸納:

解題思路:
解法: 驗證二叉搜索樹 - leetcode官方題解

臟亂差版本

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right

# 返回二叉搜索樹中,任意兩個不同節(jié)點值之間的最小差值
# 性質
# (1)二叉搜索樹。題目既然說了,那么肯定要用到該性質
# (2)任意兩個不同節(jié)點值,強調了任意兩個不同節(jié)點。但是既然是二叉搜索樹了,拿右子樹中的節(jié)點 - 左子樹中的節(jié)點肯定不會是答案,所以這里的任意其實是帶引號的"任意",不是絕對的"任意",是可以忽略一些情況的"任意"

# 以root節(jié)點為例,要查找的目標點一定是下面兩種情況
# (1)左樹的最右節(jié)點 = 左樹的最大節(jié)點 = 中序遍歷的前驅pre節(jié)點
# (2)右樹的最左節(jié)點 = 右樹的最大節(jié)點 = 中序遍歷的后繼post節(jié)點
# 最后遞歸搜索
class Solution:
    def getMinDistance(self, root: Optional[TreeNode]) -> int:
        if not root: return 0
        
        # (1)查找左樹的最'右'節(jié)點 = 左樹的最大節(jié)點
        LR = root.left
        while LR and (LR.left or LR.right):
            # 有右邊找右邊,沒右邊找左邊再找右邊
            if LR.right:
                LR = LR.right
            else:
                break
        
        # (2)查找右樹的最'左'節(jié)點 = 右樹的最大節(jié)點
        RL = root.right
        while RL and (RL.left or RL.right):
            if RL.left:
                RL = RL.left
            else:
                break

        left_result = 1e9
        if LR:            left_result = abs(root.val-LR.val)
        right_result = 1e9
        if RL:            right_result = abs(root.val-RL.val)
        return min(left_result, right_result)

    def getMinimumDifference(self, root: Optional[TreeNode]) -> int:
        result = 1e9

        # 逐個遍歷
        queue = deque([root])
        while queue:
            size = len(queue)
            for i in range(size):
                node = queue.popleft() 
                if node.left: queue.append(node.left)
                if node.right: queue.append(node.right)
                
                dis = self.getMinDistance(node)
                result = min(result, dis)
        return result

優(yōu)雅版本

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def __init__(self):
        self.result = float('inf')
        self.pre = None

    def traversal(self, cur):
        if cur is None:
            return None
        
        self.traversal(cur.left)  # 左
        
        if self.pre:  # 中
            self.result = min(self.result, cur.val - self.pre.val)
        self.pre = cur  # 記錄前一個
        
        self.traversal(cur.right)  # 右

    def getMinimumDifference(self, root):
        self.traversal(root)
        return self.result

2. 二叉搜索樹中第K小的元素

題目鏈接:二叉搜索樹中第K小的元素 - leetcode
題目描述:
給定一個二叉搜索樹的根節(jié)點 root ,和一個整數 k ,請你設計一個算法查找其中第 k 個最小元素(從 1 開始計數)。
題目歸納:
中序遍歷BST成有序數組,然后再找到這個有序數組的第k個元素?NoNoNo。掌握遞歸轉換成迭代的關鍵思想,即將"函數調用棧"明寫在代碼里。

解題思路:
解法: 二叉搜索樹中第K小的元素 - leetcode官方題解
中序遍歷的迭代寫法,注意,非遞歸!

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right

# 這道題掌握兩個知識點
# (1)中序遍歷的迭代寫法。即將函數調用棧明示出來,因為函數調用棧也是個棧,所有的遞歸寫法都是可以轉換為迭代版寫法的,手動模擬函數調用棧即可。
# (2)二叉搜索樹的中序遍歷是有序的。

class Solution:
    def kthSmallest(self, root: Optional[TreeNode], k: int) -> int:
        # 中序遍歷,迭代版而非遞歸
        stack = []
        while root or stack:
            # 相當于遞歸版寫法的左子樹遍歷
            while root: # 壓棧方向是單一的,沿著二叉樹的右上角->左下角方向壓棧
                stack.append(root)
                root = root.left
            root = stack.pop() # 遇到空就出棧
            # if root: print(root.val)
            k -= 1
            if k == 0:
                return root.val
            root = root.right

3. 驗證二叉搜索樹

題目鏈接:驗證二叉搜索樹 - leetcode
題目描述:
給定一個二叉樹的 根節(jié)點 root,想象自己站在它的右側,按照從頂部到底部的順序,返回從右側所能看到的節(jié)點值。
題目歸納:
右視圖 = 右邊的側視圖

解題思路:
解法: 驗證二叉搜索樹 - leetcode官方題解
(1) 從左到右層序遍歷。記錄層序遍歷的最后一個node,即為右視圖看到的第一個node。

經典錯誤(從局部性質推斷全局性質)

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def isValidBST(self, root: Optional[TreeNode]) -> bool:
        # 這是一道21年的408考研真題,空節(jié)點和葉節(jié)點都是二叉搜索樹
        # 注意下面的寫法是錯誤的,原因在于只判斷了局部的性質,而忽略了全局的性質
        if not root: return True
        if not root.left and not root.right: return True
        
        # (1)這個時候root肯定存在,左樹或許存在,結合root與左樹根節(jié)點,判斷是不是二叉搜索樹
        if root and root.left and root.left.val < root.val:
            return self.isValidBST(root.left)
        else:
            return False

        # (2)這個時候root肯定存在,右樹或許存在,結合root與右樹根節(jié)點,判斷是不是二叉搜索樹
        if root and root.right and root.val < root.right.val:
            return self.isValidBST(root.right)
        else:
            return False

利用第1題的代碼(有pre指針的那段)

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def __init__(self):
        self.pre = None

    def isValidBST(self, root: Optional[TreeNode]) -> bool:
        if not root:
            return True
        left = self.isValidBST(root.left)
        
        if self.pre and self.pre.val >= root.val: # __比第1題加了這個判斷__
            return False
        self.pre = root # 要遍歷root.right了,這個時候記錄pre節(jié)點
        
        right = self.isValidBST(root.right)
        
        return left and right # 兩邊都要是BST樹

附加題

1. 不同的二叉搜索樹

題目鏈接:不同的二叉搜索樹 - leetcode
題目描述:
給你一個整數 n ,求恰由 n 個節(jié)點組成且節(jié)點值從 1n 互不相同的 二叉搜索樹 有多少種?返回滿足題意的二叉搜索樹的種數。
題目歸納:
分治+動態(tài)規(guī)劃

解題思路:
解法: 不同的二叉搜索樹 - leetcode官方題解文章來源地址http://www.zghlxwxcb.cn/news/detail-819389.html

class Solution:
    def numTrees(self, n: int) -> int:
        # 給一個整數n,求恰好由n個節(jié)點組成,且節(jié)點值從1到n,能夠組成多少種不同的二叉搜索樹。
        #給定一個有序序列1...n,遍歷數字i,將數字i作為root,1 ... (i-1)序列作為左子樹,(i+1) ... n作為右子樹,接著按照同樣的方式遞歸構建左子樹和右子樹
        # 在上述構建過程中,由于根root值不同,因此能保證每棵BST是唯一的。
        
        # 采用動態(tài)規(guī)劃來求解本題
        # G(n): 長度為n的序列,所能構成的不同的BST樹的個數。注意到 G(n) 和序列的內容無關,只和序列的長度有關
        # F(i,n):以i為根、序列長度為n的不同BST的個數
        # G(n) = sum_{1}^{n}F(i,n)
        # 特別的: G(0) = 1 , G(1) = 1
        # F(i,n) = G(i-1)*G(n-i)
        # ==> G(n) = sum_{1}^{n}G(i-1)G(n-i)
        G = [0] * (n+1)
        G[0] = 1
        G[1] = 1
        for i in range(2, n+1):
            for j in range(1, i+1):
                G[i] += G[j-1] * G[i-j]
        return G[n]

到了這里,關于Leetcode面試經典150題刷題記錄 —— 二叉搜索樹篇的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!

本文來自互聯(lián)網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • 【leetcode刷題之路】面試經典150題(8)——位運算+數學+一維動態(tài)規(guī)劃+多維動態(tài)規(guī)劃

    20 位運算 20.1 【位運算】二進制求和 題目地址:https://leetcode.cn/problems/add-binary/description/?envType=study-plan-v2envId=top-interview-150 ??按位逆序運算。 20.2 【位運算】顛倒二進制位 題目地址:https://leetcode.cn/problems/reverse-bits/description/?envType=study-plan-v2envId=top-interview-150 ??詳見代碼

    2024年04月16日
    瀏覽(40)
  • LeetCode面試經典150題(day 2)

    LeetCode面試經典150題(day 2)

    26. 刪除有序數組中的重復項 難度: 簡單 ? ?給你一個? 升序排列 ?的數組? nums ?,請你 ?原地 ?刪除重復出現的元素,使每個元素? 只出現一次 ?,返回刪除后數組的新長度。元素的? 相對順序 ?應該保持? 一致 ?。然后返回? nums ?中唯一元素的個數。 考慮? nums ?的唯一

    2024年02月11日
    瀏覽(20)
  • 【LeetCode-面試經典150題-day14】

    【LeetCode-面試經典150題-day14】

    ? 目錄 19.刪除鏈表的倒數第N個結點 ?82.刪除排序鏈表中的重復元素Ⅱ ?61. 旋轉鏈表 ?86.分隔鏈表 ?146.LRU緩存 19.刪除鏈表的倒數第N個結點 題意: 給你一個鏈表,刪除鏈表的倒數第? n ? 個結點,并且返回鏈表的頭結點。 【輸入樣例】head = [1,2,3,4,5],n=2 【輸出樣例】[1,2,3,5

    2024年02月11日
    瀏覽(28)
  • 【LeetCode-經典面試150題-day12】

    20.有效的括號 題意: 給定一個只包括? \\\'(\\\' , \\\')\\\' , \\\'{\\\' , \\\'}\\\' , \\\'[\\\' , \\\']\\\' ?的字符串? s ?,判斷字符串是否有效。 有效字符串需滿足: 左括號必須用相同類型的右括號閉合。 左括號必須以正確的順序閉合。 每個右括號都有一個對應的相同類型的左括號。 【輸入樣例】s=\\\"

    2024年02月11日
    瀏覽(28)
  • LeetCode面試經典150題(day 1)

    LeetCode面試經典150題(day 1)

    LeetCode是一個免費刷題的一個網站,想要通過筆試的小伙伴可以每天堅持刷兩道算法題。 接下來,每天我將更新LeetCode面試經典150題的其中兩道算法題,一邊鞏固自己,一遍希望能幫助到有需要的小伙伴。 88.合并兩個有序數組 給你兩個按? 非遞減順序 ?排列的整數數組? nu

    2024年02月11日
    瀏覽(21)
  • LeetCode150道面試經典題-- 加一(簡單)

    LeetCode150道面試經典題-- 加一(簡單)

    給你一個非負整數 x ,計算并返回? x ?的 算術平方根 。 由于返回類型是整數,結果只保留 整數部分 ,小數部分將被 舍去 。 注意: 不允許使用任何內置指數函數和算符,例如 pow(x, 0.5) 或者 x ** 0.5 。 示例 1: 輸入:x=4 輸出:2 ? 示例 2: 輸入: x = 8 輸出: 2 解釋: 8 的

    2024年02月12日
    瀏覽(21)
  • 【LeetCode-面試經典150題-day23】

    【LeetCode-面試經典150題-day23】

    目錄 108. 將有序數組轉換為二叉搜索樹 ?148.排序鏈表 ?427.建立四叉樹 ?23.合并K個升序鏈表 ? 108. 將有序數組轉換為二叉搜索樹 題意: 給你一個整數數組? nums ?,其中元素已經按? 升序 ?排列,請你將其轉換為一棵? 高度平衡 ?二叉搜索樹。 高度平衡? 二叉樹是一棵滿足「

    2024年02月09日
    瀏覽(17)
  • 【LeetCode-經典面試150題-day11】

    目錄 128.最長連續(xù)序列 ?228.匯總區(qū)間 ?56.合并區(qū)間 ?57.插入區(qū)間 ?452.用最少數量的箭引爆氣球 ? 128.最長連續(xù)序列 題意: 給定一個未排序的整數數組? nums ?,找出數字連續(xù)的最長序列(不要求序列元素在原數組中連續(xù))的長度。 請你設計并實現時間復雜度為? O(n) ? 的算法

    2024年02月12日
    瀏覽(23)
  • LeetCode150道面試經典題-- 快樂數(簡單)

    LeetCode150道面試經典題-- 快樂數(簡單)

    編寫一個算法來判斷一個數 n 是不是快樂數。 「快樂數」 ?定義為: 對于一個正整數,每一次將該數替換為它每個位置上的數字的平方和。 然后重復這個過程直到這個數變?yōu)?1,也可能是 無限循環(huán) 但始終變不到 1。 如果這個過程 結果為 ?1,那么這個數就是快樂數。 如果

    2024年02月12日
    瀏覽(24)
  • 【leetcode面試經典150題】29.三數之和(C++)

    【leetcode面試經典150題】專欄系列將為準備暑期實習生以及秋招的同學們提高在面試時的經典面試算法題的思路和想法。本專欄將以一題多解和精簡算法思路為主,題解使用C++語言。(若有使用其他語言的同學也可了解題解思路,本質上語法內容一致) 給你一個整數數組?

    2024年04月13日
    瀏覽(23)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包