DSA Interview Prep · पाठ

Kवाँ सबसे छोटा, अंतराल योग और BST से क्रमबद्ध ऐरे

क्रमबद्ध in-order भ्रमण से O(k) में kth-smallest तत्व ढूँढ़िए और O(log n + k) में किसी अंतराल के मानों का योग निकालिए।

पाठ 4, कुल 4 में से13 चरण

Kवाँ सबसे छोटा, अंतराल योग और BST से क्रमबद्ध ऐरे, CoddyKit पर DSA Interview Prep का एक निःशुल्क पाठ है। यह 4 में से 4वाँ पाठ है। इस अध्ययन पथ के 3 तक कोई भी पाठ पूरा पढ़ना निःशुल्क है — इसके बाद CoddyKit PRO हर पाठ अनलॉक करता है, साथ ही अंतर्निर्मित कोड संपादक और चौबीसों घंटे एआई शिक्षक के साथ व्यावहारिक अभ्यास भी उपलब्ध कराता है। यह DSA Interview Prep सीखने के मार्ग का हिस्सा है और आपकी प्रगति वेब तथा CoddyKit ऐप पर सिंक होती रहती है। DSA Interview Prep पाठ्यक्रम में कुल 4 पाठ शामिल हैं।

BST में kवाँ सबसे छोटा तत्व

BST में kवाँ सबसे छोटा तत्व (LeetCode #230) एक प्रसिद्ध समस्या है, जो सीधे क्रमबद्ध इन-ऑर्डर ट्रैवर्सल का लाभ उठाती है। चूँकि इन-ऑर्डर नोड को आरोही क्रम में देखता है, इसलिए ट्रैवर्सल के दौरान नोड गिनते जाइए और count k पर मिलने वाला मान लौटाइए। समय O(h + k) है, जहाँ h ऊँचाई है (सबसे left नोड तक पहुँचने के लिए) और k इन-ऑर्डर यात्रा में लिए गए चरणों की संख्या है।

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

kवाँ सबसे छोटा: स्टैक के साथ पुनरावृत्तीय तरीका

पुनरावृत्तीय संस्करण स्पष्ट-स्टैक इन-ऑर्डर तरीके का उपयोग करता है। null तक बाएँ नोड push कीजिए, फिर pop करके गिनती कीजिए। जब गिनती k तक पहुँच जाए, तो वर्तमान नोड का मान लौटाइए। यह बहुत गहरे ट्री के लिए पाइथन की पुनरावर्तन सीमा से बचाता है और समय O(h + k) तथा स्थान O(h) में चलता है। साक्षात्कारकर्ता अक्सर पुनरावर्ती संस्करण के बाद पुनरावृत्तीय संस्करण पूछते हैं।

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

BST में kवाँ सबसे बड़ा तत्व

kवाँ सबसे बड़ा उलटे इन-ऑर्डर ट्रैवर्सल (right → मूल नोड → बायाँ) का उपयोग करता है, जो नोड को घटते क्रम में देखता है। k चरणों तक गिनिए और वर्तमान नोड का मान लौटाइए। यह kवें सबसे छोटे तत्व के सममित है और O(h + k) समय में चलता है। वैकल्पिक रूप से, यदि आपको ट्री का आकार पता हो, तो kth_smallest(root, total_count - k + 1) निकाल सकते हैं, लेकिन उलटा इन-ऑर्डर तरीका अधिक सुंदर है।

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)

BST की सीमा का योग

BST की सीमा का योग (LeetCode #938) में [low, high] के भीतर आने वाले सभी मानों का योग माँगा जाता है। शाखाओं को काटने के लिए BST गुण का उपयोग कीजिए: यदि वर्तमान नोड का मान low से कम है, तो पूरी left सबट्री भी low से नीचे है—उसे छोड़ दीजिए। यदि वर्तमान मान high से बड़ा है, तो right सबट्री छोड़ दीजिए। इससे कई शाखाएँ कट जाती हैं और यह पूर्ण इन-ऑर्डर स्कैन से अधिक कुशल होता है।

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

सीमा में नोड गिनना

[low, high] सीमा में नोड गिनना उसी शाखा-कटाई तर्क का पालन करता है। एक वैकल्पिक तरीका इन-ऑर्डर ऐरे पर bisect_left/दाएँ-विभाजन का उपयोग करता है—लेकिन सीधे BST ट्रैवर्सल की जटिलता O(log n + k) है, जबकि पहले ऐरे में बदलने की जटिलता हमेशा O(n) होती है। जब तक आपको बहुत-से सीमा संबंधी प्रश्नों के उत्तर न देने हों, सीधे ट्रैवर्सल को चुनिए; ऐसे मामले में सबट्री गणनाओं वाला संवर्धित BST बनाकर प्रत्येक प्रश्न का उत्तर O(log n) में दिया जा सकता है।

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 से क्रमबद्ध ऐरे तक (संपूर्ण कलनविधि)

BST को क्रमबद्ध ऐरे में बदलने की समय जटिलता O(n) और स्थान जटिलता O(n) है। इन-ऑर्डर ट्रैवर्सल का उपयोग कीजिए और प्रत्येक मान को append कीजिए। यह कई-चरण वाली समस्याओं का शुरुआती बिंदु है: 'दो BST को मिलाना', 'BST की मध्यिका खोजना' या 'जाँचना कि दो BST का इन-ऑर्डर अनुक्रम समान है या नहीं'। परिणामी ऐरे इंडेक्स से O(1) अभिगम, द्विआधारी खोज और दो-पॉइंटर तकनीकें उपलब्ध कराता है, जो BST स्वयं सीधे उपलब्ध नहीं कराता।

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: उपवृक्ष के आकार

एक संवर्धित BST प्रत्येक नोड पर अतिरिक्त जानकारी संग्रहीत करता है, जैसे उसके उपवृक्ष का आकार। उपवृक्षों के आकार ज्ञात होने पर kth-smallest O(log n) में प्राप्त किया जा सकता है: प्रत्येक नोड पर, यदि बाएँ उपवृक्ष का आकार k-1 है, तो वर्तमान नोड उत्तर है; यदि बाएँ उपवृक्ष का आकार k के बराबर या उससे अधिक है, तो बाएँ उपवृक्ष में दोबारा खोजें; अन्यथा k में से बाएँ उपवृक्ष का आकार घटाकर दाएँ उपवृक्ष में दोबारा खोजें। यही वह डेटा संरचना है जिसके आधार पर प्रतिस्पर्धी प्रोग्रामिंग में प्रयुक्त क्रम-सांख्यिकी वृक्ष काम करते हैं।

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')

BST में दो नोड के बीच के सभी मान खोजें

दो नोड p और q के बीच के सभी मान (जहाँ p.val < q.val) लौटाने के लिए, इन-ऑर्डर ट्रैवर्सल को सीमा-छँटाई के साथ मिलाएँ: p.val से आगे निकलने के बाद मान एकत्र करना शुरू करें और q.val के बाद रुक जाएँ। यह सीमा-योग का सामान्यीकरण है और O(h + k) समय में दोनों पूछे गए मानों के बीच का क्रमबद्ध अनुक्रम देता है।

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]

BST का माध्यिका मान

BST का माध्यिका मान इन-ऑर्डर ट्रैवर्सल का मध्य मान होता है। n नोड के लिए, माध्यिका n // 2 सूचकांक (0-आधारित) पर होती है। आप या तो पूरी क्रमबद्ध सारणी एकत्र करके उसमें उस सूचकांक का मान ले सकते हैं, या दो चरणों का उपयोग कर सकते हैं: पहले n नोड की गिनती करें, फिर दूसरा इन-ऑर्डर ट्रैवर्सल करके n // 2-वें नोड पर रुक जाएँ। वैकल्पिक रूप से, k = n // 2 + 1 के साथ kth-smallest का उपयोग करें।

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 मान

BST में किसी लक्ष्य के सबसे निकट k मान खोजें। दो-सूचक विधि में BST को क्रमबद्ध सारणी में बदलकर k आकार की एक सरकती विंडो का उपयोग करें। वैकल्पिक रूप से, k आकार के MaxHeap में दूरियाँ डालें और आकार k से अधिक होने पर मान निकाल दें। क्रमबद्ध-सारणी वाली विधि O(n) समय लेती है और सरल है; हीप वाली विधि O(n log k) समय लेती है, लेकिन प्रवाह के संदर्भ में काम करती है।

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]

उत्तराधिकारी क्रम गुण का उपयोग

BST की कई समस्याएँ क्रमबद्ध क्रम में अगले या पिछले तत्व को खोजने तक सीमित हो जाती हैं — BST नेविगेशन का उपयोग करके ये क्रियाएँ O(log n) में की जा सकती हैं। हमने पहले जो इटरेटर बनाया था, वह अगले तत्व को O(1) परिशोधित समय में देता है। kth-smallest, सीमा-योग और निकटतम-मान संबंधी ज्ञान को मिलाकर, आप BST से जुड़ी अधिकांश इंटरव्यू समस्याएँ इस प्रश्न से हल कर सकते हैं: 'इन-ऑर्डर ट्रैवर्सल का क्रमबद्ध क्रम इसे कैसे सरल बनाता है?' यही व्यापक पैटर्न 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')

त्वरित जाँच

इस पाठ में सिखाई गई डेटा संरचनाएँ और एल्गोरिदम — कोडिंग इंटरव्यू की तैयारी — संबंधी अवधारणाओं की अपनी समझ जाँचें।

पाठ का पुनरावलोकन

इस पाठ में आपने सीखा: O(h+k) में इन-ऑर्डर और रिवर्स इन-ऑर्डर ट्रैवर्सल का उपयोग करके kth smallest और largest, कुशल सीमा-प्रश्नों के लिए BST pruning के साथ range sum, और सारणी-आधारित एल्गोरिदम की नींव के रूप में BST को क्रमबद्ध सारणी में बदलना। अगले पाठ में हम हीप और प्राथमिकता कतारों का अध्ययन करेंगे।

शुरुआत निःशुल्क

एआई शिक्षक के साथ Python सीखें — निःशुल्क

अपने ब्राउज़र में वास्तविक कोड लिखें और चलाएँ, चौबीसों घंटे एआई शिक्षक से तुरंत सहायता पाएँ, और वेब या ऐप पर वहीं से शुरू करें जहाँ आपने छोड़ा था।

पाठ्यक्रम
30
पाठ
120

अक्सर पूछे जाने वाले प्रश्न

क्या “Kवाँ सबसे छोटा, अंतराल योग और BST से क्रमबद्ध ऐरे” पाठ निःशुल्क है?

हाँ — DSA Interview Prep अध्ययन पथ के 3 तक कोई भी पाठ, जिसमें “Kवाँ सबसे छोटा, अंतराल योग और BST से क्रमबद्ध ऐरे” भी शामिल है, यहाँ वेब पर पूरा पढ़ना निःशुल्क है। इसके बाद CoddyKit PRO हर पाठ अनलॉक करता है, साथ ही अंतर्निर्मित कोड संपादक और चौबीसों घंटे एआई शिक्षक के साथ इंटरैक्टिव अभ्यास भी उपलब्ध कराता है। DSA Interview Prep पाठ्यक्रम में कुल 4 पाठ शामिल हैं।

“Kवाँ सबसे छोटा, अंतराल योग और BST से क्रमबद्ध ऐरे” में मैं क्या सीखूँगा?

क्रमबद्ध in-order भ्रमण से O(k) में kth-smallest तत्व ढूँढ़िए और O(log n + k) में किसी अंतराल के मानों का योग निकालिए। आप ब्राउज़र में सीधे चलाए जाने वाले व्यावहारिक कोड के साथ DSA Interview Prep का अभ्यास करते हैं, और पाठ पूरा करते समय 24/7 एआई ट्यूटर आपके प्रश्नों के उत्तर देता है।

क्या DSA Interview Prep शुरू करने के लिए मुझे किसी अनुभव की आवश्यकता है?

पहले के अनुभव की आवश्यकता नहीं है। CoddyKit पर DSA Interview Prep शुरुआती से लेकर उन्नत शिक्षार्थियों तक सभी के लिए व्यवस्थित किया गया है, इसलिए आप यहीं से या शुरुआत से सीखना शुरू कर सकते हैं और अपनी गति से आगे बढ़ सकते हैं। यह 4 में से 4वाँ पाठ है।

“Kवाँ सबसे छोटा, अंतराल योग और BST से क्रमबद्ध ऐरे” पाठ पूरा करने में कितना समय लगता है?

CoddyKit का अधिकांश पाठ लगभग 5–10 मिनट में पूरा हो जाता है। हर पाठ छोटा और संवादात्मक है, इसलिए आप लगातार प्रगति करते हैं और वेब या ऐप पर वहीं से सीखना जारी रख सकते हैं जहाँ आपने छोड़ा था।

क्या मैं इस DSA Interview Prep पाठ में कोड लिख और चला सकता हूँ?

हाँ। हर DSA Interview Prep पाठ में एक अंतर्निर्मित कोड संपादक शामिल है, जिससे आप सीधे अपने ब्राउज़र में वास्तविक कोड लिख और चला सकते हैं और तुरंत एआई प्रतिक्रिया पा सकते हैं—स्थानीय सेटअप की आवश्यकता नहीं है।

इस पाठ्यक्रम के सभी पाठ

  1. BST में प्रविष्टि और खोज
  2. BST हटाना: तीन स्थितियाँ
  3. BST और In-Order गुणों की पुष्टि
  4. Kवाँ सबसे छोटा, अंतराल योग और BST से क्रमबद्ध ऐरे
← DSA Interview Prep पर वापस जाएँ