Verifiera BST och in-order-egenskaper
Verifiera att ett binärt träd är en BST med min/max-gränser som förs ned genom trädet och genom att kontrollera att in-order-genomgången ger en sorterad sekvens.
Verifiera BST och in-order-egenskaper är en gratis lektion i Förberedelse inför kodningsintervjuer på CoddyKit. Detta är lektion 3 av 4. Ni kan läsa hela lektionen gratis nedan och sedan öva praktiskt i webbläsaren med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt. Den ingår i lärvägen för Förberedelse inför kodningsintervjuer, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Förberedelse inför kodningsintervjuer innehåller totalt 4 lektioner.
Problemet med att validera BST
Validate BST (LeetCode #98) är en klassisk intervjufråga som ställer till det för många kandidater. Det naiva tillvägagångssättet kontrollerar bara att varje nods värde är större än dess vänsterbarn och mindre än dess högerbarn, men denna lokala kontroll räcker inte. En nod i ett delträd kan uppfylla den lokala regeln men ändå bryta mot den globala BST-egenskapen. Den korrekta lösningen för vidare minimi- och maximigränser genom trädet.
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
# Why local check fails:
# 5
# / \
# 1 4
# / \
# 3 6
# Node 4's children (3, 6) satisfy local rule,
# but 4 < 5 and is in the RIGHT subtree -- BST violated!
print('Local check is insufficient -- use min/max bounds')Metoden med minimi- och maximigränser
Skicka med undre och övre gränser i rekursionen. Kontrollera vid varje nod att low < node.val < high. När ni rekursivt går åt vänster uppdaterar ni den övre gränsen till node.val (det vänstra delträdet måste innehålla mindre värden). När ni går åt höger uppdaterar ni den undre gränsen till node.val (det högra delträdet måste innehålla större värden). Börja med low = -infinity och high = +infinity.
def is_valid_bst(root, low=float('-inf'), high=float('inf')):
if not root:
return True
if not (low < root.val < high):
return False
return (is_valid_bst(root.left, low, root.val) and
is_valid_bst(root.right, root.val, high))
# Valid BST:
valid = TreeNode(5)
valid.left = TreeNode(3)
valid.right = TreeNode(7)
print(is_valid_bst(valid)) # True
# Invalid BST (3 is in wrong subtree conceptually):
invalid = TreeNode(5)
invalid.left = TreeNode(1)
invalid.right = TreeNode(4)
invalid.right.left = TreeNode(3)
invalid.right.right = TreeNode(6)
print(is_valid_bst(invalid)) # False (4 < 5 in right subtree)Validering med inordertraversering
Ett alternativt valideringstillvägagångssätt använder BST:ts sorterade egenskap i inorderordning: samla in inordersekvensen och kontrollera att den är strikt växande. Det är elegant och lätt att resonera kring. Det kräver dock O(n) extra utrymme för att lagra sekvensen. En optimerad version använder en enda prev-pekare under traverseringen för att kontrollera varje par utan att lagra hela sekvensen.
def is_valid_bst_inorder(root):
prev = [float('-inf')]
def inorder(node):
if not node:
return True
if not inorder(node.left):
return False
if node.val <= prev[0]: # not strictly increasing
return False
prev[0] = node.val
return inorder(node.right)
return inorder(root)
valid = TreeNode(5)
valid.left = TreeNode(3)
valid.right = TreeNode(7)
valid.left.left = TreeNode(1)
valid.left.right = TreeNode(4)
print(is_valid_bst_inorder(valid)) # True
invalid = TreeNode(5)
invalid.left = TreeNode(6) # 6 > 5 in left subtree!
print(is_valid_bst_inorder(invalid)) # FalseJämförelse av de båda valideringsmetoderna
Metoden med minimi- och maximigränser har tidskomplexiteten O(n) och rymdkomplexiteten O(h) (endast gränserna på anropsstacken). Metoden med inordertraversering och prev-pekare har också O(n) tid och O(h) utrymme. Båda är optimala. Metoden med minimi- och maximigränser är mer generell och fungerar smidigt när den utvidgas till problem med ytterligare begränsningar. Var beredda att presentera båda metoderna i intervjuer och diskutera avvägningarna – att känna till alternativen är en stark signal.
# Both approaches:
# Time: O(n) -- visit each node once
# Space: O(h) -- call stack depth
# h = O(log n) balanced, O(n) skewed
# When to choose which:
# min/max bounds:
# - Cleaner for trees with constraints beyond BST
# - No global state (purely functional)
# in-order prev:
# - More intuitive (sorted sequence check)
# - Easier to convert to iterative with a stack
print('Both O(n) time, O(h) space -- choose by clarity')Återställ BST: två noder har bytt plats
Recover BST (LeetCode #99) reparerar ett BST där exakt två noder har bytt plats. Under inordertraverseringen ger ett korrekt ordnat BST en sorterad sekvens. Om två noder har bytt plats uppstår en eller två avvikelser där prev.val > current.val. Den första noden i den första avvikelsen och den andra noden i den sista avvikelsen är de två felplacerade noderna – byt plats på deras värden.
def recover_tree(root):
first = second = prev = None
def inorder(node):
nonlocal first, second, prev
if not node:
return
inorder(node.left)
if prev and prev.val > node.val:
if not first:
first = prev # first violator
second = node # always update second
prev = node
inorder(node.right)
inorder(root)
# Swap values of the two misplaced nodes
if first and second:
first.val, second.val = second.val, first.val
root = TreeNode(3)
root.left = TreeNode(1)
root.right = TreeNode(4)
root.right.left = TreeNode(2) # 2 and 3 are swapped
recover_tree(root)
print(root.val, root.right.left.val) # 2, 3 (fixed)Från BST:s inorderordning till en sorterad array
Att konvertera ett BST till en sorterad array är enkelt: utför en inordertraversering och samla in värdena. Denna operation tar O(n) tid och O(n) utrymme och är ett snabbt sätt att använda algoritmer för sorterade arrayer (binärsökning, två pekare) på BST-data. Det är ofta ett delsteg i problem med flera delar, till exempel att "slå ihop två BST:er" eller "hitta medianen i ett BST".
def bst_to_sorted_array(root):
result = []
def inorder(node):
if not node:
return
inorder(node.left)
result.append(node.val)
inorder(node.right)
inorder(root)
return result
root = TreeNode(4)
root.left = TreeNode(2)
root.right = TreeNode(6)
root.left.left = TreeNode(1)
root.left.right = TreeNode(3)
root.right.left = TreeNode(5)
root.right.right = TreeNode(7)
print(bst_to_sorted_array(root)) # [1, 2, 3, 4, 5, 6, 7]Slå ihop två BST
För att slå ihop två BST till en sorterad array konverterar ni vart och ett till en sorterad array på O(n) respektive O(m), och slår sedan ihop de två sorterade arrayerna med merge-steget från merge sort på O(n+m). Den totala tiden är O(n+m). Om resultatet ska vara ett balanserat BST skickar ni den sammanslagna sorterade arrayen till algoritmen för att konvertera en sorterad array till ett BST. Denna uppdelning i enkla delproblem kännetecknar en tydlig och intervjuvänlig lösning.
def merge_two_bsts(root1, root2):
def inorder(node, arr):
if not node:
return
inorder(node.left, arr)
arr.append(node.val)
inorder(node.right, arr)
arr1, arr2 = [], []
inorder(root1, arr1)
inorder(root2, arr2)
# Merge two sorted arrays
merged = []
i = j = 0
while i < len(arr1) and j < len(arr2):
if arr1[i] <= arr2[j]:
merged.append(arr1[i]); i += 1
else:
merged.append(arr2[j]); j += 1
merged.extend(arr1[i:])
merged.extend(arr2[j:])
return merged
r1 = TreeNode(2); r1.left = TreeNode(1); r1.right = TreeNode(4)
r2 = TreeNode(3); r2.left = TreeNode(0); r2.right = TreeNode(5)
print(merge_two_bsts(r1, r2)) # [0, 1, 2, 3, 4, 5]Räkna noder inom ett intervall i BST
Räkna hur många noder som har värden inom intervallet [low, high]. En brute force-genomgång i inorderordning tar O(n). Den BST-anpassade versionen beskär sökningen: om den aktuella nodens värde är mindre än low finns det ingen anledning att kontrollera det vänstra delträdet (alla värden där är också mindre än low). På samma sätt kan det högra delträdet beskäras när det aktuella värdet är större än high. Den genomsnittliga tidskomplexiteten är O(log n + k), där k är antalet matchande noder.
def range_sum_bst(root, low, high):
if not root:
return 0
total = 0
if low <= root.val <= high:
total += root.val
if root.val > low: # left subtree may have values >= low
total += range_sum_bst(root.left, low, high)
if root.val < high: # right subtree may have values <= high
total += range_sum_bst(root.right, low, high)
return total
root = TreeNode(10)
root.left = TreeNode(5)
root.right = TreeNode(15)
root.left.left = TreeNode(3)
root.left.right = TreeNode(7)
root.right.right = TreeNode(18)
print(range_sum_bst(root, 7, 15)) # 7 + 10 + 15 = 32Dubblettvärden och strikt kontra icke-strikt BST
Den vanliga BST-invarianten använder strikt olikhet: värdena i det vänstra delträdet är strikt mindre och värdena i det högra delträdet är strikt större. Vissa problem tillåter dubbletter och placerar dem i det vänstra delträdet (left <= root) eller det högra delträdet (root < right). Kontrollera alltid definitionen i problemformuleringen när ni validerar BST:n. Metoden med minimi- och maximigränser hanterar båda varianterna genom att justera om gränskontrollen ska vara strikt eller inklusiv.
# Strict BST (LeetCode default): left < root < right
def is_valid_strict(root, lo=float('-inf'), hi=float('inf')):
if not root:
return True
if not (lo < root.val < hi): # STRICT inequalities
return False
return (is_valid_strict(root.left, lo, root.val) and
is_valid_strict(root.right, root.val, hi))
# Non-strict BST (allows duplicates in right): left <= root < right
def is_valid_nonstrict(root, lo=float('-inf'), hi=float('inf')):
if not root:
return True
if not (lo <= root.val < hi): # NOTE: <= for left side
return False
return (is_valid_nonstrict(root.left, lo, root.val + 1) and
is_valid_nonstrict(root.right, root.val, hi))
print('Always clarify strict vs non-strict with interviewer')Inorder som universellt BST-verktyg
Inordertraversering är BST-problemens schweiziska armékniv. När ett BST-problem handlar om sorterad ordning, ett k:te element, intervallfrågor eller sekvensegenskaper bör ni överväga om en inordergenomgång (eller dess omvända variant) ger svaret. De flesta BST-specifika problem kan reduceras till: gå igenom noderna i sorterad ordning och gör något vid varje steg. Att snabbt känna igen denna koppling är en viktig intervjufärdighet.
# Problems solved elegantly with in-order:
# 1. Validate BST: check prev <= curr during in-order
# 2. Kth smallest: count k steps in in-order
# 3. Kth largest: count k steps in REVERSE in-order
# 4. Closest value to target: find crossover in in-order
# 5. BST to sorted array: collect in-order into list
# 6. Recover BST: find 1-2 violations in in-order
# 7. Sum of range [lo, hi]: accumulate during in-order
# The key insight: in-order visits BST nodes in sorted order.
# All sorted-order reasoning translates to in-order DFS.
print('In-order = sorted access = foundation of BST reasoning')Närmaste värde i BST
Hitta den nod vars värde ligger närmast ett givet målvärde. Använd BST:ts ordning: börja vid roten, håll reda på det närmaste värdet hittills och gå mot målvärdet (gå åt vänster om målvärdet är mindre och åt höger om det är större). Denna metod tar O(h) tid, är effektivare än en inordergenomgång och visar hur BST-egenskapen kan användas för att beskära sökutrymmet.
def closest_value(root, target):
closest = root.val
curr = root
while curr:
if abs(curr.val - target) < abs(closest - target):
closest = curr.val
if target < curr.val:
curr = curr.left
elif target > curr.val:
curr = curr.right
else:
break # exact match
return closest
root = TreeNode(4)
root.left = TreeNode(2)
root.right = TreeNode(5)
root.left.left = TreeNode(1)
root.left.right = TreeNode(3)
print(closest_value(root, 3.714286)) # 4Snabbkontroll
Testa er förståelse av begreppen Data Structures & Algorithms — Coding Interview Prep från den här lektionen.
Sammanfattning av lektionen
I den här lektionen lärde ni er: BST-validering med minimi- och maximigränser (så att fallgropen med lokala kontroller undviks), alternativet med en inorder- och prev-pekare för validering samt inorder som det universella BST-verktyget för intervallsummor, närmaste värde och sammanslagningsoperationer. Härnäst använder vi BST:ts inorder-egenskaper för att hitta det k:te minsta elementet.
Lär dig Förberedelse inför kodningsintervjuer med en AI-lärare – gratis
Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.
- Kurser
- 90
- Lektioner
- 360
Vanliga frågor
Är lektionen ”Verifiera BST och in-order-egenskaper” gratis?
Ja – hela texten till ”Verifiera BST och in-order-egenskaper” kan läsas gratis här på webben. Om Ni vill öva interaktivt med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt och låsa upp resten av kursen i Förberedelse inför kodningsintervjuer, kan Ni uppgradera till CoddyKit PRO. Kursen i Förberedelse inför kodningsintervjuer innehåller totalt 4 lektioner.
Vad lär jag mig i ”Verifiera BST och in-order-egenskaper”?
Verifiera att ett binärt träd är en BST med min/max-gränser som förs ned genom trädet och genom att kontrollera att in-order-genomgången ger en sorterad sekvens. Ni övar på Förberedelse inför kodningsintervjuer med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.
Behöver jag någon erfarenhet för att börja lära mig Förberedelse inför kodningsintervjuer?
Du behöver inga förkunskaper. Utbildningen i Förberedelse inför kodningsintervjuer på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 3 av 4.
Hur lång tid tar lektionen ”Verifiera BST och in-order-egenskaper”?
De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.
Kan jag skriva och köra kod i den här Förberedelse inför kodningsintervjuer-lektionen?
Ja. Varje Förberedelse inför kodningsintervjuer-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.
Alla lektioner i den här kursen
- Infogning och sökning i BST
- Ta bort från BST: tre fall
- Verifiera BST och in-order-egenskaper
- K:te minsta, intervallsumma och BST till sorterad array