Aralık Çizelgeleme ve Birleştirme
Toplantı odaları ve çakışmayan aralıklar problemlerini bitiş zamanına göre sıralayarak çözün; aralıkları başlangıç zamanına göre sıralayarak birleştirin.
Aralık Çizelgeleme ve Birleştirme, CoddyKit'te ücretsiz bir DSA Interview Prep dersidir. Bu, 4 dersinin 2. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, DSA Interview Prep öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. DSA Interview Prep kursu toplamda 4 dersten oluşur.
Aralık Problemlerine Genel Bakış
Aralık problemleri, çizelgeleme, takvim yönetimi ve kaynak tahsisi mülakatlarında sürekli karşınıza çıkar. Temel kalıplar şunlardır: çakışan aralıkları birleştirme, minimum toplantı odası sayısını bulma, çakışmayan en büyük kümeyi bulma ve yeni bir aralık insert etme. Çoğu aralık problemi aynı adımla başlar: aralıkları başlangıç zamanına göre sort etme (probleme bağlı olarak bitiş zamanına göre de olabilir). Doğru sıralama anahtarını seçmek çoğu zaman en zor kısımdır.
# Intervals: each = [start, end] (inclusive or exclusive by problem)
# Example:
intervals = [[1,3],[2,6],[8,10],[15,18]]
# Sorted by start (already sorted here)
# Visually:
# [1,3] |-|
# [2,6] |---|
# [8,10] |--|
# [15,18] |---|
print('Intervals ready for analysis')Çakışan Aralıkları Birleştirme
Aralıkları Birleştirme (LeetCode 56): bir aralık listesi verildiğinde, çakışan tüm aralıkları birleştirin. Algoritma: başlangıç zamanına göre sort edin. Sıralanmış listede ilerleyin; mevcut aralık son birleştirilmiş aralıkla çakışıyorsa (başlangıcı ≤ son birleştirilmiş aralığın end değeri), son birleştirilmiş aralığın end değerini iki bitişin maksimumuna çıkarın. Aksi halde mevcut aralığı yeni birleştirilmiş aralık olarak append edin. Time: Sıralama için O(n log n), birleştirme için O(n).
def merge_intervals(intervals):
intervals.sort(key=lambda x: x[0]) # sort by start
merged = [intervals[0]]
for start, end in intervals[1:]:
last_end = merged[-1][1]
if start <= last_end:
# Overlapping: extend the last interval
merged[-1][1] = max(last_end, end)
else:
# Non-overlapping: add as new interval
merged.append([start, end])
return merged
print(merge_intervals([[1,3],[2,6],[8,10],[15,18]]))
# [[1,6],[8,10],[15,18]]
print(merge_intervals([[1,4],[4,5]]))
# [[1,5]] (touching intervals merge)Aralık Ekleme
Aralık Ekleme (LeetCode 57): sıralanmış ve çakışmayan bir liste verildiğinde yeni bir aralık ekleyin ve aralıkları yeniden birleştirin. Üç aşamada ilerleyin: (1) Yeni aralık başlamadan önce end olan tüm aralıkları ekleyin. (2) Yeni aralıkla çakışan tüm aralıkları birleştirin (sınırlarını genişletin). (3) Geriye kalan tüm aralıkları ekleyin. Bu problemde sort işlemi zaten yapılmış olduğundan, O(n log n) sıralamadan sonra tek bir O(n) geçiş yeterlidir.
def insert_interval(intervals, new_interval):
result = []
i = 0
n = len(intervals)
# Phase 1: intervals before new_interval
while i < n and intervals[i][1] < new_interval[0]:
result.append(intervals[i])
i += 1
# Phase 2: merge overlapping intervals
while i < n and intervals[i][0] <= new_interval[1]:
new_interval[0] = min(new_interval[0], intervals[i][0])
new_interval[1] = max(new_interval[1], intervals[i][1])
i += 1
result.append(new_interval)
# Phase 3: remaining intervals
while i < n:
result.append(intervals[i])
i += 1
return result
print(insert_interval([[1,3],[6,9]], [2,5])) # [[1,5],[6,9]]
print(insert_interval([[1,2],[3,5],[6,7],[8,10],[12,16]], [4,8]))
# [[1,2],[3,10],[12,16]]Toplantı Odaları I: Tümüne Katılabilir misiniz?
Toplantı Odaları I (LeetCode 252): toplantı zaman aralıkları verildiğinde, bir kişinin tüm toplantılara katılıp katılamayacağını belirleyin. Başlangıç zamanına göre sıralayın; herhangi bir toplantı önceki toplantı bitmeden başlıyorsa toplantılar çakışır. Bu, en basit aralık denetimidir ve toplam karmaşıklığı O(n log n)'dir. Temel fikir şudur: Sıralamadan sonra yalnızca ardışık çiftleri karşılaştırmanız gerekir.
def can_attend_meetings(intervals):
intervals.sort(key=lambda x: x[0])
for i in range(1, len(intervals)):
# Current meeting starts before previous ends?
if intervals[i][0] < intervals[i-1][1]:
return False
return True
print(can_attend_meetings([[0,30],[5,10],[15,20]])) # False (0,30 overlaps 5,10)
print(can_attend_meetings([[7,10],[2,4]])) # True (4 < 7, no overlap)Toplantı Odaları II: Minimum Oda Sayısı
Toplantı Odaları II (LeetCode 253): tüm toplantıları aynı anda gerçekleştirmek için gereken minimum konferans odası sayısını bulun. En erken biten odayı izlemek için bir minimum yığını kullanın. Toplantıları başlangıç zamanına göre sıralayın. Her yeni toplantı için: toplantı en erken biten odanın end zamanından sonra başlıyorsa odayı yeniden kullanın (pop işlemi yapıp ekleyin). Aksi halde yeni bir oda açın. Sondaki yığın boyutu, gereken oda sayısına eşittir.
import heapq
def min_meeting_rooms(intervals):
if not intervals: return 0
intervals.sort(key=lambda x: x[0]) # sort by start
heap = [] # min-heap of end times
for start, end in intervals:
if heap and heap[0] <= start:
heapq.heapreplace(heap, end) # reuse earliest-ending room
else:
heapq.heappush(heap, end) # open a new room
return len(heap)
print(min_meeting_rooms([[0,30],[5,10],[15,20]])) # 2
print(min_meeting_rooms([[7,10],[2,4]])) # 1
print(min_meeting_rooms([[9,10],[4,9],[4,17]])) # 2Oda Sayısı İçin Tarama Çizgisi Alternatifi
Alternatif bir O(n log n) yaklaşım da tarama çizgisidir. Her aralık başlangıcı (+1) ve bitişi (-1) için olaylar oluşturun. Tüm olayları time değerine göre sıralayın (eşitlik durumunda, uç noktalar dahil değilse end olayını start olayından önce sıralayın). Soldan sağa tarama yaparken devam eden toplantıların sayısını tutun. En büyük sayı, gereken minimum oda sayısıdır. Bu yaklaşım bazı kişiler için daha sezgiseldir ve aralıklar üzerindeki diğer sayma problemlerine de genellenebilir.
def min_rooms_sweep(intervals):
events = []
for start, end in intervals:
events.append((start, 1)) # meeting starts
events.append((end, -1)) # meeting ends
# Sort: same time → end (-1) before start (1) if exclusive
events.sort(key=lambda x: (x[0], x[1]))
max_rooms = current = 0
for _, delta in events:
current += delta
max_rooms = max(max_rooms, current)
return max_rooms
print(min_rooms_sweep([[0,30],[5,10],[15,20]])) # 2
print(min_rooms_sweep([[1,5],[2,6],[3,7]])) # 3 (all overlap at t=3)Çakışmayan Aralıklar: Maksimum Seçim
Çakışmayan Aralıklar (LeetCode 435): kalan aralıkların çakışmamasını sağlamak için silinmesi gereken minimum aralık sayısını bulun. Bu, çakışmayan aralıkların maksimum sayısını (etkinlik seçimi) bulmaya ve geri kalanları silinecekler olarak döndürmeye eşdeğerdir. Bitiş zamanına göre sıralayın: en erken biten aralığı açgözlü biçimde tutun (gelecekteki aralıklar için en fazla alanı bırakır). Sonraki aralık çakıştığında onu discard edin (bir silme işlemi sayın).
def erase_overlap_intervals(intervals):
if not intervals: return 0
intervals.sort(key=lambda x: x[1]) # sort by END time
removals = 0
last_end = float('-inf')
for start, end in intervals:
if start >= last_end:
last_end = end # keep this interval
else:
removals += 1 # remove this interval (it overlaps)
return removals
print(erase_overlap_intervals([[1,2],[2,3],[3,4],[1,3]])) # 1 (remove [1,3])
print(erase_overlap_intervals([[1,2],[1,2],[1,2]])) # 2
print(erase_overlap_intervals([[1,2],[2,3]])) # 0 (no overlap)Başlangıç Zamanına Değil, Bitiş Zamanına Göre Sıralama Nedeni
Etkinlik seçimi (çakışmayan en büyük küme) için bitiş zamanına göre sıralamanın en iyi olduğu kanıtlanmıştır. Sezgi şöyledir: erken biten bir etkinlik, gelecekteki etkinlikler için daha fazla alan bırakır. Başlangıç zamanına göre sıralarsak, çok erken başlayan ve uzun süren bir etkinliği seçip daha sonra başlayacak birçok kısa etkinliğin önünü kesebiliriz. Değiş tokuş argümanı: En iyi çözüm, en erken biten G yerine A etkinliğini seçiyorsa A'yı G ile değiştirin — G daha geç bitmediği için A'nın çakıştığı hiçbir etkinlikle çakışmaz.
# Counterexample for sorting by START time:
# [[1,10],[2,3],[4,5]] — sorted by start: [1,10],[2,3],[4,5]
# Sort-by-start greedy keeps [1,10], can't add [2,3] or [4,5] (all overlap [1,10])
# Selects: 1 interval
# Sort-by-end greedy:
# [[2,3],[4,5],[1,10]] — sorted by end
# Keep [2,3] (end=3), then [4,5] (start=4 >= 3, keep), then [1,10] (start=1 < 5, skip)
# Selects: 2 intervals — OPTIMAL
intervals = [[1,10],[2,3],[4,5]]
intervals.sort(key=lambda x: x[1])
last_end = float('-inf')
count = 0
for s, e in intervals:
if s >= last_end:
count += 1; last_end = e
print('Max non-overlapping:', count) # 2Aralık Kesişimlerinin Listesi
Aralık Kesişimlerinin Listesi (LeetCode 986): sıralanmış iki aralık listesindeki tüm kesişen çiftleri bulun. İki işaretçili bir yaklaşım kullanın. Her adımda mevcut çiftin kesişimini hesaplayın (başlangıçların maksimumu, bitişlerin minimumu). Başlangıç ≤ bitiş ise kesişim geçerlidir. Ardından, daha önce biten aralığın işaretçisini ilerletin. Zaman karmaşıklığı O(m+n)'dir.
def interval_intersection(A, B):
result = []
i = j = 0
while i < len(A) and j < len(B):
# Intersection boundaries
lo = max(A[i][0], B[j][0])
hi = min(A[i][1], B[j][1])
if lo <= hi:
result.append([lo, hi]) # valid intersection
# Advance pointer of interval that ends first
if A[i][1] < B[j][1]:
i += 1
else:
j += 1
return result
A = [[0,2],[5,10],[13,23],[24,25]]
B = [[1,5],[8,12],[15,24],[25,26]]
print(interval_intersection(A, B))
# [[1,2],[5,5],[8,10],[15,23],[24,24],[25,25]]Bölüm Etiketleri
Bölüm Etiketleri (LeetCode 763): her karakterin en fazla bir bölümde yer alacağı şekilde bir dizeyi mümkün olduğunca çok parçaya ayırın. Açgözlü yaklaşım: her karakter için son görülme konumunu bulun. max_end değerini koruyarak dizede ilerleyin. i == max_end olduğunda mevcut bölüm tamamlanmıştır — uzunluğunu kaydedin ve yeni bir bölüm başlatın. Bu, görünüşte bir aralık birleştirme problemidir.
def partition_labels(s):
last = {c: i for i, c in enumerate(s)} # last occurrence of each char
partitions = []
start = max_end = 0
for i, c in enumerate(s):
max_end = max(max_end, last[c])
if i == max_end: # partition complete
partitions.append(max_end - start + 1)
start = i + 1
return partitions
print(partition_labels('ababcbacadefegdehijhklij'))
# [9, 7, 8] — parts 'ababcbaca', 'defegde', 'hijhklij'Aralık Problemlerinin Özeti
Aralıklar için şu dört kalıbı öğrenin: (1) Birleştirme: başlangıca göre sıralayın, örtüşme varsa son aralığı genişletin. (2) Oda sayma: başlangıca göre sıralayın, bitiş zamanlarından oluşan bir minimum yığını kullanın. (3) Çakışmayan en büyük küme: bitişe göre sıralayın ve açgözlü biçimde seçim yapın. (4) Ekleme: üç aşamalı doğrusal tarama. Sıralama anahtarı önemlidir: birleştirme başlangıcı, maksimum seçim ise bitişi kullanır. Sıralamanın belirleyici olması nedeniyle zaman karmaşıklığı her zaman O(n log n)'dir; birleştirme ve tarama O(n)'dir.
# Quick reference:
# Merge intervals: sort by start, extend if overlap
# Insert interval: three-phase linear scan
# Meeting rooms (can?): sort by start, check consecutive overlap
# Meeting rooms (min?): sort by start, min-heap of end times / sweep
# Max non-overlapping: sort by END, greedy keep
# Min removals: n - max_non_overlapping
# Interval intersection: two pointers on sorted lists
print('Pattern: sort key is the decisive choice')
print('Merge → sort by start')
print('Activity selection → sort by end')
print('Room count → sort by start + heap of ends')Hızlı Kontrol
Bu dersteki Veri Yapıları ve Algoritmalar — Kodlama Mülakatına Hazırlık kavramlarını anlayıp anlamadığınızı test edin.
Ders Özeti
Bu derste şunları öğrendiniz: aralıkları başlangıca göre sıralayıp örtüşme oluştuğunda son aralığı genişleterek birleştirmeyi, minimum toplantı odası sayısını bulmak için başlangıca göre sıralama ile bitiş zamanlarından oluşan bir minimum yığını kullanmayı ve en erken biten oda boşaldığında odayı yeniden kullanmayı ve çakışmayan en büyük aralık kümesini bitiş zamanına göre açgözlü seçimle bulmayı. Sırada, açgözlü aralık genişletmeyle çözülen erişilebilirlik ve minimum sıçrama problemleri olan Sıçrama Oyunu I ve II var.
Sıkça Sorulan Sorular
“Aralık Çizelgeleme ve Birleştirme” dersi ücretsiz mi?
Evet — “Aralık Çizelgeleme ve Birleştirme” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve DSA Interview Prep kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. DSA Interview Prep kursu toplamda 4 dersten oluşur.
“Aralık Çizelgeleme ve Birleştirme” dersinde ne öğreneceğim?
Toplantı odaları ve çakışmayan aralıklar problemlerini bitiş zamanına göre sıralayarak çözün; aralıkları başlangıç zamanına göre sıralayarak birleştirin. DSA Interview Prep ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.
DSA Interview Prep öğrenmeye başlamak için deneyim gerekli mi?
Önceden deneyim gerekmez. CoddyKit'te DSA Interview Prep, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 4 dersinin 2. dersidir.
“Aralık Çizelgeleme ve Birleştirme” dersi ne kadar sürer?
Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.
Bu DSA Interview Prep dersinde kod yazıp çalıştırabilir miyim?
Evet. Her DSA Interview Prep dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.
Bu kursun tüm dersleri
- Açgözlü Yaklaşım mı DP mi: Hangisi Ne Zaman Kullanılır
- Aralık Çizelgeleme ve Birleştirme
- Sıçrama Oyunu I ve II
- Görev Çizelgeleyici ve Benzin İstasyonu