DSA Interview Prep · Pelajaran

Unsur Ke-K Terkecil, Jumlah Julat dan BST kepada Tatasusunan Tersusun

Manfaatkan lintasan dalam susunan yang tersusun untuk mencari unsur ke-k terkecil dalam O(k) dan menjumlahkan nilai dalam julat dalam O(log n + k).

Pelajaran 4 daripada 413 langkah

Unsur Ke-K Terkecil, Jumlah Julat dan BST kepada Tatasusunan Tersusun ialah pelajaran DSA Interview Prep percuma di CoddyKit. Ini ialah pelajaran 4 daripada 4. Sebanyak 3 pelajaran dalam laluan pembelajaran ini boleh dibaca sepenuhnya secara percuma — selepas itu, CoddyKit PRO membuka akses kepada semua pelajaran, serta latihan praktikal dengan penyunting kod terbina dalam dan tutor kecerdasan buatan yang tersedia 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran DSA Interview Prep, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus DSA Interview Prep merangkumi sejumlah 4 pelajaran.

Elemen ke-k Terkecil dalam BST

Elemen ke-k Terkecil dalam BST (LeetCode #230) ialah masalah klasik yang memanfaatkan lintasan tertib-dalam tersusun secara langsung. Oleh sebab lintasan tertib-dalam melawati nod dalam susunan menaik, kita hanya perlu mengira nod semasa melintasi pokok dan mengembalikan nilai pada kiraan k. Masa ialah O(h + k), dengan h ialah ketinggian (untuk mencapai nod paling kiri) dan k ialah bilangan langkah dalam lintasan tertib-dalam.

class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

def kth_smallest(root, k):
    count = [0]
    result = [None]

    def inorder(node):
        if not node or result[0] is not None:
            return
        inorder(node.left)
        count[0] += 1
        if count[0] == k:
            result[0] = node.val
            return
        inorder(node.right)

    inorder(root)
    return result[0]

root = TreeNode(3)
root.left = TreeNode(1)
root.right = TreeNode(4)
root.left.right = TreeNode(2)
print(kth_smallest(root, 1))  # 1
print(kth_smallest(root, 2))  # 2

Elemen ke-k Terkecil: Secara Lelaran dengan Timbunan

Versi lelaran menggunakan corak tertib-dalam dengan timbunan eksplisit. Masukkan nod kiri sehingga tiada nod lagi, kemudian lakukan pop dan kira. Apabila kiraan mencapai k, kembalikan nilai nod semasa. Kaedah ini mengelakkan had rekursi Python untuk pokok yang sangat dalam dan juga mengambil masa O(h + k) serta ruang O(h). Penemu duga sering meminta versi lelaran selepas versi rekursif.

def kth_smallest_iterative(root, k):
    stack = []
    curr = root
    count = 0
    while curr or stack:
        while curr:             # go as far left as possible
            stack.append(curr)
            curr = curr.left
        curr = stack.pop()      # process node
        count += 1
        if count == k:
            return curr.val
        curr = curr.right       # move to right subtree
    return -1  # k out of range

root = TreeNode(5)
root.left = TreeNode(3)
root.right = TreeNode(6)
root.left.left = TreeNode(2)
root.left.right = TreeNode(4)
root.left.left.left = TreeNode(1)
print(kth_smallest_iterative(root, 3))  # 3

Elemen ke-k Terbesar dalam BST

Elemen ke-k Terbesar menggunakan lintasan tertib-dalam terbalik (kanan → akar → kiri), yang melawati nod dalam susunan menurun. Kira k langkah dan kembalikan nilai nod semasa. Kaedah ini merupakan pasangan simetri kepada elemen ke-k terkecil dan mengambil masa O(h + k). Sebagai alternatif, kira kth_smallest(root, total_count - k + 1) jika anda mengetahui saiz pokok, tetapi pendekatan tertib-dalam terbalik lebih kemas.

def kth_largest(root, k):
    count = [0]
    result = [None]

    def reverse_inorder(node):
        if not node or result[0] is not None:
            return
        reverse_inorder(node.right)   # visit LARGER values first
        count[0] += 1
        if count[0] == k:
            result[0] = node.val
            return
        reverse_inorder(node.left)

    reverse_inorder(root)
    return result[0]

root = TreeNode(3)
root.left = TreeNode(1)
root.right = TreeNode(4)
root.left.right = TreeNode(2)
print(kth_largest(root, 1))  # 4 (largest)
print(kth_largest(root, 2))  # 3 (2nd largest)

Jumlah Julat BST

Jumlah Julat BST (LeetCode #938) meminta jumlah semua nilai dalam [low, high]. Manfaatkan sifat BST untuk memangkas: jika nilai nod semasa lebih kecil daripada sempadan bawah, keseluruhan subpokok kiri juga berada di bawah sempadan bawah — langkau subpokok itu. Jika nilai semasa lebih besar daripada sempadan atas, langkau subpokok right. Kaedah ini memangkas banyak cabang dan lebih cekap daripada imbasan tertib-dalam penuh.

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 might have values >= low
        total += range_sum_bst(root.left, low, high)
    if root.val < high:   # right subtree might 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 = 32

Mengira Nod dalam Julat

Mengira nod dalam julat [low, high] mengikut logik pemangkasan yang sama. Alternatifnya menggunakan bisect_left/bisect_right pada tatasusunan tertib-dalam — tetapi lintasan BST secara langsung mengambil masa O(log n + k), manakala penukaran kepada tatasusunan terlebih dahulu sentiasa mengambil masa O(n). Pilih lintasan langsung melainkan anda perlu menjawab banyak pertanyaan julat; dalam keadaan itu, membina BST diperkaya dengan kiraan subpokok membolehkan O(log n) bagi setiap pertanyaan.

def count_range(root, low, high):
    if not root:
        return 0
    count = 0
    if low <= root.val <= high:
        count += 1
    if root.val > low:
        count += count_range(root.left, low, high)
    if root.val < high:
        count += count_range(root.right, low, high)
    return count

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(count_range(root, 6, 15))  # 7, 10, 15 = 3

BST kepada Tatasusunan Tersusun (Algoritma Penuh)

Menukar BST kepada tatasusunan tersusun mengambil masa O(n) dan ruang O(n). Gunakan lintasan tertib-dalam dan append setiap nilai. Ini ialah titik permulaan bagi masalah berbilang langkah: “gabungkan dua BST”, “cari median BST” atau “semak sama ada dua BST mempunyai jujukan tertib-dalam yang sama”. Tatasusunan yang terhasil menyokong capaian O(1) mengikut indeks, carian binari dan teknik dua penuding yang tidak dapat disediakan secara langsung oleh BST itu sendiri.

def bst_to_sorted(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(5)
root.left = TreeNode(3)
root.right = TreeNode(8)
root.left.left = TreeNode(1)
root.left.right = TreeNode(4)
root.right.left = TreeNode(6)
root.right.right = TreeNode(9)
print(bst_to_sorted(root))  # [1, 3, 4, 5, 6, 8, 9]

# Binary search on the resulting sorted array:
import bisect
arr = bst_to_sorted(root)
print(bisect.bisect_left(arr, 6))   # 4 (index of 6)

BST Diperkaya: Saiz Subpokok

BST yang diperkaya menyimpan maklumat tambahan pada setiap nod, seperti saiz subpokoknya. Dengan saiz subpokok, kth-smallest menjadi O(log n): pada setiap nod, jika saiz subpokok kiri ialah k-1, nod semasa ialah jawapannya; jika saiz kiri >= k, teruskan secara rekursif ke kiri; jika tidak, kurangkan k sebanyak saiz subpokok kiri dan teruskan secara rekursif ke kanan. Inilah struktur data di sebalik pokok statistik tertib yang digunakan dalam pengaturcaraan kompetitif.

class AugNode:
    def __init__(self, val):
        self.val = val
        self.left = None
        self.right = None
        self.size = 1  # subtree size

def get_size(node):
    return node.size if node else 0

def update_size(node):
    if node:
        node.size = 1 + get_size(node.left) + get_size(node.right)

def kth_smallest_aug(root, k):
    left_size = get_size(root.left)
    if k == left_size + 1:
        return root.val      # current node is kth
    elif k <= left_size:
        return kth_smallest_aug(root.left, k)
    else:
        return kth_smallest_aug(root.right, k - left_size - 1)

print('Augmented BST: O(log n) kth smallest with subtree sizes')

Cari Semua Nilai dalam BST antara Dua Nod

Untuk mengembalikan semua nilai yang terletak tepat antara dua nod p dan q (dengan p.val < q.val), gabungkan lintasan mengikut tertib dengan pemangkasan julat: mula mengumpulkan nilai selepas melepasi p.val dan berhenti selepas q.val. Ini ialah pengitlakan kepada jumlah julat dan memberikan urutan tersusun antara dua nilai pertanyaan dalam O(h + k) time.

def values_between(root, low, high):
    result = []
    def inorder(node):
        if not node:
            return
        if node.val > low:    # might be values > low on left
            inorder(node.left)
        if low < node.val < high:  # strictly between
            result.append(node.val)
        if node.val < high:   # might be values < high on right
            inorder(node.right)
    inorder(root)
    return result

root = TreeNode(10)
root.left = TreeNode(5)
root.right = TreeNode(15)
root.left.left = TreeNode(3)
root.left.right = TreeNode(7)
root.right.left = TreeNode(12)
root.right.right = TreeNode(18)
print(values_between(root, 6, 15))  # [7, 10, 12]

Median BST

Median BST ialah nilai tengah dalam lintasan mengikut tertib. Bagi n nod, median berada pada indeks n // 2 (berindeks sifar). Anda boleh mengumpulkan keseluruhan tatasusunan tersusun lalu mendapatkan elemennya berdasarkan indeks, atau menggunakan dua lintasan: mula-mula kira n nod, kemudian lakukan lintasan mengikut tertib yang kedua dan berhenti pada nod ke-n // 2. Sebagai alternatif, gunakan kth-smallest dengan k = n // 2 + 1.

def count_nodes(root):
    if not root:
        return 0
    return 1 + count_nodes(root.left) + count_nodes(root.right)

def median_of_bst(root):
    n = count_nodes(root)
    if n == 0:
        return None
    k = n // 2 + 1  # (n+1)/2-th element for odd, n/2+1-th for even
    return kth_smallest(root, k)

def kth_smallest(root, k):
    count = [0]; result = [None]
    def inorder(node):
        if not node or result[0] is not None: return
        inorder(node.left)
        count[0] += 1
        if count[0] == k: result[0] = node.val; return
        inorder(node.right)
    inorder(root); return result[0]

root = TreeNode(5)
root.left = TreeNode(3)
root.right = TreeNode(8)
root.left.left = TreeNode(1)
root.left.right = TreeNode(4)
print(median_of_bst(root))  # 4 (middle of [1,3,4,5,8])

K Nilai Terdekat dengan Sasaran

Cari k nilai dalam BST yang paling hampir dengan sasaran. Satu pendekatan dua penuding ialah menukarkan BST kepada tatasusunan tersusun dan menggunakan tetingkap gelongsor bersaiz k. Sebagai alternatif, gunakan timbunan maksimum bersaiz k, lakukan push bagi jarak, dan lakukan pop apabila saiznya melebihi k. Pendekatan tatasusunan tersusun mengambil O(n) time dan mudah; pendekatan timbunan mengambil O(n log k), tetapi sesuai dalam konteks penstriman.

import heapq

def closest_k_values(root, target, k):
    # Collect sorted values
    arr = []
    def inorder(node):
        if not node: return
        inorder(node.left)
        arr.append(node.val)
        inorder(node.right)
    inorder(root)

    # Two-pointer sliding window of size k
    left, right = 0, k - 1
    while right < len(arr) - 1:
        if abs(arr[left] - target) <= abs(arr[right + 1] - target):
            break  # left is closer, don't advance
        left += 1
        right += 1
    return arr[left:right + 1]

root = TreeNode(4)
root.left = TreeNode(2)
root.right = TreeNode(5)
root.left.left = TreeNode(1)
root.left.right = TreeNode(3)
print(closest_k_values(root, 3.7, 2))  # [3, 4]

Memanfaatkan Sifat Susunan Pengganti

Banyak masalah BST dapat dikurangkan kepada pencarian elemen seterusnya atau sebelumnya dalam susunan tersusun — operasi yang mengambil O(log n) menggunakan navigasi BST. Lelaran yang kita bina sebelum ini memberikan operasi seterusnya dalam O(1) secara teramortisasi. Dengan menggabungkan pengetahuan tentang kth-smallest, jumlah julat dan nilai terdekat, anda boleh menyelesaikan kebanyakan masalah temu duga BST dengan bertanya: “Bagaimanakah susunan tersusun bagi lintasan mengikut tertib memudahkan masalah ini?” Corak meta ini ialah panduan anda untuk menyelesaikan masalah BST.

# Meta-pattern for BST problems:
# Step 1: What sorted-order property does this exploit?
# Step 2: Is in-order (ascending) or reverse in-order (descending) needed?
# Step 3: Can I prune using BST ordering to avoid O(n) scan?

# Quick reference:
# kth smallest  -> in-order, stop at kth node
# kth largest   -> reverse in-order, stop at kth node
# range sum     -> in-order + BST pruning
# closest value -> walk toward target, track best
# median        -> kth with k = n//2+1
# sorted array  -> full in-order
# validate      -> in-order prev check or min/max bounds
print('Sorted in-order is the universal BST problem tool')

Semakan Pantas

Uji pemahaman anda tentang konsep Struktur Data & Algoritma — Persediaan Temu Duga Pengekodan daripada pelajaran ini.

Imbas Kembali Pelajaran

Dalam pelajaran ini, anda mempelajari: kth-smallest dan terbesar menggunakan lintasan mengikut tertib dan lintasan mengikut tertib songsang dalam O(h+k), jumlah julat dengan pemangkasan BST untuk pertanyaan julat yang cekap, serta penukaran BST kepada tatasusunan tersusun sebagai asas kepada algoritma berasaskan tatasusunan. Seterusnya, kita meneroka timbunan dan baris gilir keutamaan.

Percuma untuk bermula

Pelajari Python dengan tutor kecerdasan buatan — percuma

Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.

Kursus
30
Pelajaran
120

Soalan Lazim

Adakah pelajaran “Unsur Ke-K Terkecil, Jumlah Julat dan BST kepada Tatasusunan Tersusun” percuma?

Ya — sebanyak 3 pelajaran dalam laluan pembelajaran DSA Interview Prep, termasuk “Unsur Ke-K Terkecil, Jumlah Julat dan BST kepada Tatasusunan Tersusun”, boleh dibaca sepenuhnya secara percuma di web ini. Selepas itu, CoddyKit PRO membuka akses kepada semua pelajaran, serta latihan interaktif dengan penyunting kod terbina dalam dan tutor kecerdasan buatan yang tersedia 24/7. Kursus DSA Interview Prep merangkumi sejumlah 4 pelajaran.

Apakah yang akan saya pelajari dalam “Unsur Ke-K Terkecil, Jumlah Julat dan BST kepada Tatasusunan Tersusun”?

Manfaatkan lintasan dalam susunan yang tersusun untuk mencari unsur ke-k terkecil dalam O(k) dan menjumlahkan nilai dalam julat dalam O(log n + k). Anda berlatih DSA Interview Prep menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.

Adakah saya memerlukan pengalaman untuk memulakan DSA Interview Prep?

Tiada pengalaman terdahulu diperlukan. Pembelajaran DSA Interview Prep di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 4 daripada 4.

Berapa lamakah pelajaran “Unsur Ke-K Terkecil, Jumlah Julat dan BST kepada Tatasusunan Tersusun” diambil?

Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.

Bolehkah saya menulis dan menjalankan kod dalam pelajaran DSA Interview Prep ini?

Ya. Setiap pelajaran DSA Interview Prep menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.

Semua pelajaran dalam kursus ini

  1. Sisipan dan Carian BST
  2. Pemadaman BST: Tiga Kes
  3. Mengesahkan BST dan Sifat Dalam Susunan
  4. Unsur Ke-K Terkecil, Jumlah Julat dan BST kepada Tatasusunan Tersusun
← Kembali ke DSA Interview Prep