उपस्ट्रिंग के लिए स्लाइडिंग विंडो
दोहराए गए अक्षरों के बिना सबसे लंबी उपस्ट्रिंग और सभी लक्ष्य अक्षरों वाली न्यूनतम विंडो खोजने के लिए परिवर्तनीय आकार की स्लाइडिंग विंडो लागू कीजिए।
उपस्ट्रिंग के लिए स्लाइडिंग विंडो, CoddyKit पर कोडिंग साक्षात्कार की तैयारी का एक निःशुल्क पाठ है। यह 4 में से 2वाँ पाठ है। आप नीचे पूरा पाठ निःशुल्क पढ़ सकते हैं—फिर अंतर्निहित कोड संपादक और 24/7 एआई ट्यूटर के साथ ब्राउज़र में इसका व्यावहारिक अभ्यास कर सकते हैं। यह कोडिंग साक्षात्कार की तैयारी सीखने के मार्ग का हिस्सा है और आपकी प्रगति वेब तथा CoddyKit ऐप पर सिंक होती रहती है। कोडिंग साक्षात्कार की तैयारी पाठ्यक्रम में कुल 4 पाठ शामिल हैं।
स्लाइडिंग विंडो की अवधारणा
एक स्लाइडिंग विंडो बाएँ और दाएँ सूचक के बीच एक उप-सरणी (या उप-स्ट्रिंग) बनाए रखती है। प्रत्येक संभावित उप-सरणी के गुणों को O(n²) समय में नए सिरे से निकालने के बजाय, विंडो एक तत्व जोड़कर दाईं ओर फैलती है और एक तत्व हटाकर बाईं ओर सिकुड़ती है; इस दौरान हर चरण में O(1) समय में वर्तमान स्थिति बनाए रखी जाती है। इससे O(n) समय वाला एल्गोरिदम मिलता है। इसे 'स्लाइडिंग' इसलिए कहा जाता है क्योंकि यह पीछे जाए बिना सरणी में आगे बढ़ती रहती है।
# Fixed-size window sum: O(n) after O(k) setup
def max_sum_window(nums, k):
window_sum = sum(nums[:k]) # initial window
best = window_sum
for i in range(k, len(nums)):
window_sum += nums[i] # add new right
window_sum -= nums[i - k] # remove old left
best = max(best, window_sum)
return best
print(max_sum_window([2,1,5,1,3,2], 3)) # 9 ([5,1,3])निश्चित और परिवर्ती विंडो आकार
स्लाइडिंग विंडो के दो प्रकार होते हैं। निश्चित आकार वाली विंडो में दोनों सूचक एक ही गति से आगे बढ़ते हैं और विंडो में हमेशा ठीक k तत्व होते हैं। परिवर्ती आकार वाली विंडो में दायाँ सूचक लालचपूर्वक आगे बढ़ता है और बायाँ सूचक केवल तब सिकुड़ता है जब विंडो किसी बाधा का उल्लंघन करती है। परिवर्ती आकार वाली विंडो ऐसी समस्याएँ हल करती हैं जैसे 'दोहराव वाले वर्णों के बिना सबसे लंबी उप-स्ट्रिंग', जिसमें पहले से इष्टतम विंडो आकार ज्ञात नहीं होता।
# Variable window: longest substring with at most k distinct chars
def longest_k_distinct(s, k):
from collections import defaultdict
freq = defaultdict(int)
left = 0
best = 0
for right in range(len(s)):
freq[s[right]] += 1
while len(freq) > k: # window invalid: shrink
freq[s[left]] -= 1
if freq[s[left]] == 0:
del freq[s[left]]
left += 1
best = max(best, right - left + 1)
return best
print(longest_k_distinct('eceba', 2)) # 3 ('ece')
print(longest_k_distinct('aa', 1)) # 2दोहराव रहित सबसे लंबी उप-स्ट्रिंग
यह परिवर्ती स्लाइडिंग विंडो की सबसे प्रसिद्ध समस्या है। वर्तमान विंडो में मौजूद वर्णों को ट्रैक करने के लिए एक समुच्चय का उपयोग कीजिए। दाईं ओर विस्तार कीजिए; जब कोई दोहराया हुआ वर्ण मिले, तो बाईं ओर से तब तक सिकोड़िए जब तक वह दोहराव हट न जाए। तेज़ संस्करण में प्रत्येक वर्ण का नवीनतम सूचकांक रखने वाला हैश मानचित्र उपयोग होता है। इससे बायाँ सूचक धीरे-धीरे आगे बढ़ने के बजाय एक ही चरण में दोहराए गए वर्ण के आगे पहुँच जाता है।
def length_of_longest_substring(s):
char_idx = {} # char -> last seen index
left = 0
best = 0
for right, c in enumerate(s):
if c in char_idx and char_idx[c] >= left:
left = char_idx[c] + 1 # jump past duplicate
char_idx[c] = right
best = max(best, right - left + 1)
return best
print(length_of_longest_substring('abcabcbb')) # 3 ('abc')
print(length_of_longest_substring('bbbbb')) # 1
print(length_of_longest_substring('pwwkew')) # 3 ('wke')न्यूनतम विंडो वाली उप-स्ट्रिंग
s और t स्ट्रिंग दिए होने पर, s में t के सभी वर्णों वाली सबसे छोटी विंडो ढूँढिए। दो आवृत्ति मानचित्रों का उपयोग कीजिए: need (आवश्यक वर्ण) और have (वर्तमान विंडो में आवश्यकता पूरी करने वाले वर्ण)। t के कितने विशिष्ट वर्णों की आवश्यकता पूरी हो चुकी है, इसे ट्रैक कीजिए (formed गणक)। वर्णों को शामिल करने के लिए दाईं ओर विस्तार कीजिए; जब t के सभी वर्ण शामिल हो जाएँ, तो विंडो को छोटा करने के लिए बाईं ओर से सिकोड़िए। समय O(|s| + |t|)।
from collections import Counter
def min_window(s, t):
if not t or not s: return ''
need = Counter(t)
have = {}
formed = 0
required = len(need)
left = 0
best = float('inf'), 0, 0
for right, c in enumerate(s):
have[c] = have.get(c, 0) + 1
if c in need and have[c] == need[c]:
formed += 1
while formed == required:
if right - left + 1 < best[0]:
best = right - left + 1, left, right
have[s[left]] -= 1
if s[left] in need and have[s[left]] < need[s[left]]:
formed -= 1
left += 1
return s[best[1]:best[2]+1] if best[0] != float('inf') else ''
print(min_window('ADOBECODEBANC', 'ABC')) # 'BANC'स्लाइडिंग विंडो का ढाँचा
अधिकांश परिवर्ती स्लाइडिंग विंडो समस्याएँ एक ही ढाँचे का पालन करती हैं: नया वर्ण शामिल करने के लिए दाईं ओर विस्तार कीजिए, विंडो की स्थिति अद्यतन कीजिए, वैधता जाँचिए और यदि विंडो अमान्य हो, तो उसके फिर से वैध होने तक बाईं ओर से सिकोड़ते जाइए। मुख्य समझ यह है कि बायाँ सूचक केवल आगे बढ़ता है — वह कभी पीछे नहीं जाता — इसलिए सिकोड़ने वाले सभी चरणों में कुल कार्य O(n) ही रहता है। विंडो प्रत्येक तत्व को अधिकतम दो बार देखती है (एक बार जोड़ते समय और एक बार हटाते समय)।
def sliding_window_template(s, condition_check, update_state, remove_state):
"""
Generic sliding window skeleton.
Adapt condition_check, update_state, remove_state per problem.
"""
left = 0
state = {} # or whatever state you need
best = 0
for right in range(len(s)):
update_state(state, s[right]) # expand window
while not condition_check(state): # window invalid
remove_state(state, s[left]) # shrink window
left += 1
best = max(best, right - left + 1)
return bestस्ट्रिंग में क्रमचय
जाँचिए कि क्या पैटर्न p का कोई क्रमचय s की उप-स्ट्रिंग के रूप में मौजूद है। क्रमचय की जाँच ऐसी विंडो के बराबर है जिसमें p के समान वर्ण-आवृत्तियाँ हों। ठीक len(p) वर्णों वाली स्लाइडिंग विंडो बनाए रखें और आवृत्ति-गणनाओं की तुलना करें। हर चरण में पूरे गणना-संग्रह ऑब्जेक्ट की तुलना O(26) समय लेती है (छोटे अंग्रेज़ी अक्षरों के लिए यह स्थिर है), इसलिए कुल समय O(n × 26) = O(n) होता है।
from collections import Counter
def check_inclusion(p, s):
if len(p) > len(s): return False
need = Counter(p)
window = Counter(s[:len(p)])
if need == window: return True
for right in range(len(p), len(s)):
left = right - len(p)
window[s[right]] += 1
window[s[left]] -= 1
if window[s[left]] == 0:
del window[s[left]]
if window == need:
return True
return False
print(check_inclusion('ab', 'eidbaooo')) # True ('ba')
print(check_inclusion('ab', 'eidboaoo')) # Falseएनाग्राम उप-स्ट्रिंग: सभी की गणना
s में p के एनाग्रामों के सभी आरंभिक सूचकांक ढूँढिए। यह स्ट्रिंग में क्रमचय वाली समस्या जैसी ही निश्चित-विंडो तकनीक है, लेकिन पहली मिलान वाली स्थिति पर True लौटाने के बजाय हम सभी मिलान वाली स्थितियाँ एकत्र करते हैं। विंडो का आकार len(p) पर निश्चित रहता है; हम इसे s पर आगे बढ़ाते हैं और हर चरण में आवृत्ति-गणनाओं की तुलना करते हैं।
from collections import Counter
def find_anagrams(s, p):
result = []
need = Counter(p)
k = len(p)
window = Counter(s[:k])
if window == need:
result.append(0)
for right in range(k, len(s)):
window[s[right]] += 1
left_char = s[right - k]
window[left_char] -= 1
if window[left_char] == 0:
del window[left_char]
if window == need:
result.append(right - k + 1)
return result
print(find_anagrams('cbaebabacd', 'abc')) # [0, 6]अधिकतम 2 भिन्न वर्णों वाली सबसे लंबी उप-स्ट्रिंग
यह स्लाइडिंग विंडो का एक रूप है: अधिकतम 2 भिन्न वर्णों वाली सबसे लंबी उप-स्ट्रिंग ढूँढिए। वर्तमान विंडो के वर्णों का आवृत्ति मानचित्र बनाए रखें। जब मानचित्र में 2 से अधिक प्रविष्टियाँ हो जाएँ, तो बाएँ सूचक को दाईं ओर ले जाएँ (आवृत्ति घटाएँ और शून्य होने पर प्रविष्टि हटा दें), जब तक बाधा फिर से पूरी न हो जाए। यह 'अधिकतम k भिन्न वर्णों' वाली समस्या का k=2 वाला विशेष रूप है।
def longest_substring_two_distinct(s):
from collections import defaultdict
freq = defaultdict(int)
left = 0
best = 0
for right, c in enumerate(s):
freq[c] += 1
while len(freq) > 2:
freq[s[left]] -= 1
if freq[s[left]] == 0:
del freq[s[left]]
left += 1
best = max(best, right - left + 1)
return best
print(longest_substring_two_distinct('eceba')) # 3 ('ece')
print(longest_substring_two_distinct('ccaabbb')) # 5 ('aabbb')स्लाइडिंग विंडो का अधिकतम
k आकार की प्रत्येक विंडो में अधिकतम मान ढूँढिए। हर विंडो का अधिकतम मान बलपूर्वक जाँचने में O(n×k) समय लगता है। सबसे अच्छा तरीका सूचकांकों वाले एकरूपी डेक का उपयोग करता है: घटते क्रम वाला डेक बनाए रखें, ताकि उसका अगला सिरा हमेशा वर्तमान विंडो के अधिकतम मान के सूचकांक पर हो। जब सूचकांक विंडो से बाहर निकलें, तो उन्हें अगले सिरे से हटाएँ; जब कोई बड़ा तत्व आए, तो पीछे के सिरे से छोटे सूचकांक हटाएँ। कुल समय O(n) है।
from collections import deque
def max_sliding_window(nums, k):
dq = deque() # stores indices, decreasing values
result = []
for i, n in enumerate(nums):
# Remove indices outside window
while dq and dq[0] < i - k + 1:
dq.popleft()
# Maintain decreasing order
while dq and nums[dq[-1]] < n:
dq.pop()
dq.append(i)
if i >= k - 1: # window is full
result.append(nums[dq[0]])
return result
print(max_sliding_window([1,3,-1,-3,5,3,6,7], 3))
# [3, 3, 5, 5, 6, 7]स्लाइडिंग विंडो का उपयोग कब करें
जब आपको ये संकेत दिखाई दें, तो स्लाइडिंग विंडो का उपयोग कीजिए:
- किसी बाधा वाली उप-स्ट्रिंग / उप-सरणी (अधिकतम लंबाई, योग = k, अधिकतम k भिन्न वर्ण)
- समेकन वाली निश्चित आकार की विंडो (अधिकतम, योग, आवृत्ति)
- सन्निहित श्रेणी से जुड़े प्रश्न (मनमाने उपसमुच्चय नहीं)
# Recognising sliding window problems:
# 1. Fixed window: 'maximum average of subarray of length k'
def max_avg(nums, k):
s = sum(nums[:k])
best = s
for i in range(k, len(nums)):
s += nums[i] - nums[i-k]
best = max(best, s)
return best / k
print(max_avg([1,12,-5,-6,50,3], 4)) # 12.75
# 2. Variable window: 'smallest subarray with sum >= target'
def min_sub_len(target, nums):
left = s = 0
best = float('inf')
for right, n in enumerate(nums):
s += n
while s >= target:
best = min(best, right - left + 1)
s -= nums[left]; left += 1
return 0 if best == float('inf') else best
print(min_sub_len(7, [2,3,1,2,4,3])) # 2मान्य विंडो की गणना: अधिकतम K
कुछ समस्याओं में ऐसी उप-सरणियों की संख्या पूछी जाती है जो किसी शर्त को पूरा करती हैं। एक उपयोगी युक्ति यह है: अधिकतम k भिन्न वर्णों वाली उप-सरणियों की संख्या गिनिए, फिर ठीक k पाने के लिए घटाइए: exactly(k) = at_most(k) - at_most(k-1)। इस गणना के प्रत्येक आह्वान में O(n) समय लगता है, इसलिए कुल समय O(n) रहता है। अधिकतम-k वाला फ़ंक्शन उन विंडो की गणना करता है जिनमें भिन्न वर्णों की संख्या k से अधिक नहीं होती। इसके लिए right - left + 1 का योग किया जाता है (हर right के लिए सभी मान्य left अंतिम बिंदु)।
from collections import defaultdict
def subarrays_at_most_k(s, k):
freq = defaultdict(int)
left = 0
count = 0
for right, c in enumerate(s):
freq[c] += 1
while len(freq) > k:
freq[s[left]] -= 1
if freq[s[left]] == 0: del freq[s[left]]
left += 1
count += right - left + 1 # all valid windows ending at right
return count
def subarrays_exactly_k(s, k):
return subarrays_at_most_k(s, k) - subarrays_at_most_k(s, k-1)
print(subarrays_exactly_k('araaci', 2)) # 9त्वरित जाँच
इस पाठ में सिखाई गई डेटा संरचनाएँ और एल्गोरिदम — कोडिंग साक्षात्कार की तैयारी से जुड़ी अवधारणाओं की अपनी समझ जाँचिए।
पाठ का पुनरावलोकन
इस पाठ में आपने सीखा: स्लाइडिंग विंडो O(n²) समय को समाप्त करती है, क्योंकि वह एक चलती हुई विंडो की स्थिति बनाए रखती है और तत्वों के जुड़ने या हटने पर उसे O(1) समय में अद्यतन करती है, निश्चित आकार वाली विंडो में दोनों सूचक एक ही गति से आगे बढ़ते हैं; परिवर्ती आकार वाली विंडो दाईं ओर लालचपूर्वक फैलती है और केवल बाधा का उल्लंघन होने पर बाईं ओर सिकुड़ती है, और न्यूनतम विंडो वाली उप-स्ट्रिंग तथा स्ट्रिंग में क्रमचय — दोनों आवृत्ति-मानचित्र वाली विंडो स्थिति का उपयोग करते हैं, जिसमें एक गणक यह ट्रैक करता है कि कितने आवश्यक वर्णों की आवश्यकता अभी पूरी हुई है। आगे हम एनाग्राम और वर्ण-आवृत्ति मानचित्रों का अध्ययन करेंगे।
एआई शिक्षक के साथ कोडिंग साक्षात्कार की तैयारी सीखें — निःशुल्क
अपने ब्राउज़र में वास्तविक कोड लिखें और चलाएँ, चौबीसों घंटे एआई शिक्षक से तुरंत सहायता पाएँ, और वेब या ऐप पर वहीं से शुरू करें जहाँ आपने छोड़ा था।
- पाठ्यक्रम
- 90
- पाठ
- 360
अक्सर पूछे जाने वाले प्रश्न
क्या “उपस्ट्रिंग के लिए स्लाइडिंग विंडो” पाठ निःशुल्क है?
हाँ—“उपस्ट्रिंग के लिए स्लाइडिंग विंडो” का पूरा पाठ यहाँ वेब पर निःशुल्क पढ़ा जा सकता है। इंटरैक्टिव अभ्यास (अंतर्निहित कोड संपादक और 24/7 एआई ट्यूटर) करने और कोडिंग साक्षात्कार की तैयारी पाठ्यक्रम का बाकी हिस्सा अनलॉक करने के लिए CoddyKit PRO लें। कोडिंग साक्षात्कार की तैयारी पाठ्यक्रम में कुल 4 पाठ शामिल हैं।
“उपस्ट्रिंग के लिए स्लाइडिंग विंडो” में मैं क्या सीखूँगा?
दोहराए गए अक्षरों के बिना सबसे लंबी उपस्ट्रिंग और सभी लक्ष्य अक्षरों वाली न्यूनतम विंडो खोजने के लिए परिवर्तनीय आकार की स्लाइडिंग विंडो लागू कीजिए। आप ब्राउज़र में सीधे चलाए जाने वाले व्यावहारिक कोड के साथ कोडिंग साक्षात्कार की तैयारी का अभ्यास करते हैं, और पाठ पूरा करते समय 24/7 एआई ट्यूटर आपके प्रश्नों के उत्तर देता है।
क्या कोडिंग साक्षात्कार की तैयारी शुरू करने के लिए मुझे किसी अनुभव की आवश्यकता है?
पहले के अनुभव की आवश्यकता नहीं है। CoddyKit पर कोडिंग साक्षात्कार की तैयारी शुरुआती से लेकर उन्नत शिक्षार्थियों तक सभी के लिए व्यवस्थित किया गया है, इसलिए आप यहीं से या शुरुआत से सीखना शुरू कर सकते हैं और अपनी गति से आगे बढ़ सकते हैं। यह 4 में से 2वाँ पाठ है।
“उपस्ट्रिंग के लिए स्लाइडिंग विंडो” पाठ पूरा करने में कितना समय लगता है?
CoddyKit का अधिकांश पाठ लगभग 5–10 मिनट में पूरा हो जाता है। हर पाठ छोटा और संवादात्मक है, इसलिए आप लगातार प्रगति करते हैं और वेब या ऐप पर वहीं से सीखना जारी रख सकते हैं जहाँ आपने छोड़ा था।
क्या मैं इस कोडिंग साक्षात्कार की तैयारी पाठ में कोड लिख और चला सकता हूँ?
हाँ। हर कोडिंग साक्षात्कार की तैयारी पाठ में एक अंतर्निर्मित कोड संपादक शामिल है, जिससे आप सीधे अपने ब्राउज़र में वास्तविक कोड लिख और चला सकते हैं और तुरंत एआई प्रतिक्रिया पा सकते हैं—स्थानीय सेटअप की आवश्यकता नहीं है।
इस पाठ्यक्रम के सभी पाठ
- साक्षात्कारों के लिए Python स्ट्रिंग API
- उपस्ट्रिंग के लिए स्लाइडिंग विंडो
- Anagram और अक्षर-आवृत्ति मानचित्र
- स्ट्रिंग एन्कोडिंग, उलटना और Palindrome