Big-O Gösterimine Sıfırdan Başlama
Asimptotik büyümeyi neden önemsediğimizi, sabitleri ve düşük dereceli terimleri nasıl göz ardı edeceğinizi ve Big-O gösterimini bir bakışta nasıl okuyacağınızı anlayın.
Big-O Gösterimine Sıfırdan Başlama, CoddyKit'te ücretsiz bir Coding Interview Prep dersidir. Bu, 4 dersinin 1. 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, Coding Interview Prep öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. Coding Interview Prep kursu toplamda 4 dersten oluşur.
Algoritma Verimliliği Neden Ölçülür
İki program da doğru olabilir; ancak biri göz açıp kapayıncaya kadar tamamlanırken diğeri saatlerce çalışabilir. Zaman karmaşıklığı, girdi büyüdükçe çalışma süresinin nasıl arttığını açıklar.
# O(n) approach
def find_max_linear(nums):
m = nums[0]
for n in nums:
if n > m: m = n
return m
# O(n^2) approach (unnecessary double loop)
def find_max_quadratic(nums):
for i in range(len(nums)):
is_max = all(nums[i] >= nums[j] for j in range(len(nums)))
if is_max: return nums[i]
print(find_max_linear([3, 1, 4, 1, 5, 9])) # 9Big-O: Asimptotik Üst Sınır
Big-O, maliyetin ne kadar hızlı büyüdüğüne ilişkin en kötü durum üst sınırını açıklar. Yöntem şudur: Sabitleri ve daha küçük terimleri atın; çünkü büyük ölçekte yalnızca baskın terim önemlidir. Koda bakın.
# T(n) = 3n^2 + 5n + 100 is O(n^2)
# because the n^2 term dominates for large n
# T(n) = 2n + 1000 is O(n)
# the constant 1000 becomes negligible
# Rule: drop constants and lower-order terms
# 5n^3 + 2n^2 + n + 1 => O(n^3)
# 100 * log(n) + n => O(n)
print('O(n^2) example: counting iterations')
n = 1000
count = sum(1 for i in range(n) for j in range(n))
print(count) # 1_000_000 = n^2Yaygın Karmaşıklık Sınıfları
En hızlıdan en yavaşa: O(1), O(log n), O(n), O(n log n), O(n^2), O(2^n), O(n!). Bunları bilmek, tek bir satır yazmadan önce doğru yaklaşımı seçmenizi sağlar.
import math
n = 1000
print(f'O(1): {1}')
print(f'O(log n): {int(math.log2(n))}')
print(f'O(n): {n}')
print(f'O(n log n): {int(n * math.log2(n))}')
print(f'O(n^2): {n**2}')
# O(2^n) for n=1000 is astronomically large
# O(n!) even largerSabitleri Atmak: Neden Önemlidir
5n adım çalıştırmak da 2n adım çalıştırmak da O(n) değerindedir; sabitler algoritmaya değil, donanıma bağlıdır. Büyük O, aynı koşullarda ölçeklenmeyi karşılaştırabilmeniz için bu sabitleri göz ardı eder.
# Both are O(n) — different constants
def count_a(n):
total = 0
for i in range(n): # n ops
total += 1
for i in range(n): # n ops
total += 1
return total # T(n) = 2n => O(n)
def count_b(n):
total = 0
for i in range(5 * n): # 5n ops
total += 1
return total # T(n) = 5n => O(n)
print(count_a(10), count_b(10)) # 20 50En İyi, Ortalama ve En Kötü Durumlar
Büyük O en kötü durumu ifade eder; Omega en iyi durumu, Theta ise her ikisi için sıkı bir sınırı ifade eder. Bir mülakatçı "karmaşıklık" dediğinde neredeyse her zaman en kötü durumu kasteder.
def linear_search(nums, target):
for i, n in enumerate(nums):
if n == target:
return i # best case: target at index 0 => O(1)
return -1 # worst case: not found => O(n)
# Best case O(1): target is first element
print(linear_search([5,1,2,3], 5)) # 0
# Worst case O(n): target not in list
print(linear_search([1,2,3,4], 9)) # -1O(log n): Arama Alanını Yarıya İndirmek
Bir algoritma her adımda girdiyi yarıya indiriyorsa, ikili aramada olduğu gibi, O(log n) değerindedir. Bir milyar öğe için bile bu yalnızca yaklaşık 30 adımdır; inanılmaz derecede hızlıdır. Kodu inceleyin.
def binary_search(arr, target):
lo, hi = 0, len(arr) - 1
steps = 0
while lo <= hi:
steps += 1
mid = (lo + hi) // 2
if arr[mid] == target:
return mid, steps
elif arr[mid] < target:
lo = mid + 1
else:
hi = mid - 1
return -1, steps
import math
arr = list(range(1000))
idx, s = binary_search(arr, 999)
print(f'Found at {idx} in {s} steps (log2(1000)~={math.log2(1000):.1f})')O(n log n): Sıralamanın Alt Sınırı
Karşılaştırmalı her sıralama algoritması, en kötü durumda en az O(n log n) adım gerektirir; bu gerçek bir matematiksel alt sınırdır. Bu nedenle önce sıralayıp sonra taramak genel olarak O(n log n) değerindedir, O(n^2) değil. Kodda birleştirmeli sıralama gösteriliyor.
# Merge sort: O(n log n)
def merge_sort(arr):
if len(arr) <= 1:
return arr
mid = len(arr) // 2
left = merge_sort(arr[:mid])
right = merge_sort(arr[mid:])
return merge(left, right)
def merge(a, b):
res, i, j = [], 0, 0
while i < len(a) and j < len(b):
if a[i] <= b[j]: res.append(a[i]); i+=1
else: res.append(b[j]); j+=1
return res + a[i:] + b[j:]
print(merge_sort([5,2,8,1,9,3])) # [1,2,3,5,8,9]Amortismanlı Karmaşıklık
Amortismanlı analiz, maliyeti çok sayıda işlem üzerine yayarak ortalamasını alır. Python'daki append amortismanlı olarak O(1) değerindedir: çoğu zaman anında gerçekleşir; nadir görülen O(n) boyutlandırma maliyeti tüm append işlemlerine küçük paylar hâlinde dağıtılır.
# Dynamic array append is O(1) amortised
import sys
lst = []
capacities = []
for i in range(16):
lst.append(i)
capacities.append(sys.getsizeof(lst))
# Size jumps show reallocation events
for i, c in enumerate(capacities):
if i > 0 and capacities[i] != capacities[i-1]:
print(f'Realloc at i={i}, new size={c} bytes')Kodda Karmaşıklığı Tanımak
Hızlı bir kural: döngüleri sayın. Tek döngü O(n), iç içe iki döngü O(n^2), yarıya inen bir döngü O(log n) değerindedir. Bağımsız geçişler add; yalnızca iç içe döngüler çarpar. Kodu inceleyin.
# Two independent passes: O(n) + O(n) = O(n)
def two_passes(nums):
total = sum(nums) # O(n)
mean = total / len(nums)
diffs = [abs(n - mean) for n in nums] # O(n)
return max(diffs) # O(n)
# Overall: O(n) -- NOT O(n^2)
# Nested loops: O(n) * O(n) = O(n^2)
def all_pairs(nums):
pairs = []
for i in range(len(nums)): # O(n)
for j in range(i+1, len(nums)): # O(n)
pairs.append((nums[i], nums[j]))
return pairs # O(n^2)Uzay Karmaşıklığının Temelleri
Uzay karmaşıklığı, girdi dışında kullandığınız ek belleği izler. Yerinde ters çevirme O(1), bir karma tablosu ise O(n) değerindedir. Zamanı alanla değiş tokuş ettiğinizde her zaman ikisini de belirtin.
# O(1) space: reverse in-place
def reverse_inplace(arr):
l, r = 0, len(arr) - 1
while l < r:
arr[l], arr[r] = arr[r], arr[l]
l += 1; r -= 1
# O(n) space: create reversed copy
def reverse_copy(arr):
return arr[::-1]
a = [1, 2, 3, 4, 5]
reverse_inplace(a)
print(a) # [5, 4, 3, 2, 1]Mülakatlarda Karmaşıklıktan Söz Etmek
Sorulmasını beklemeden her zaman karmaşıklığı kendiniz belirtin: "Bu işlem O(n log n) zaman ve O(n) alan kullanır." Ardından daha hızlı bir seçenek sunun. Bu alışkanlık gerçek bir kıdem göstergesidir.
# Example of explaining complexity step by step
def two_sum(nums, target):
# O(n) time: one pass through nums
# O(n) space: hash map stores up to n elements
seen = {} # value -> index
for i, n in enumerate(nums):
complement = target - n
if complement in seen: # O(1) lookup
return [seen[complement], i]
seen[n] = i
return []
print(two_sum([2, 7, 11, 15], 9)) # [0, 1]Hızlı Kontrol
Hızlı kontrol — Büyük O ve karmaşıklık sınıfları hakkında öğrendiklerinizi gösterin. Tek bir soru var; bunu yapabilirsiniz. 🎯
Ders Özeti
Özet: Büyük O, sabitlerin göz ardı edildiği en kötü durum büyümesini ifade eder; O(1)'den O(n!)'e kadar olan sınıfları biliyorsunuz ve bağımsız döngüler toplanırken iç içe döngüler çarpılır.
Sıkça Sorulan Sorular
“Big-O Gösterimine Sıfırdan Başlama” dersi ücretsiz mi?
Evet — “Big-O Gösterimine Sıfırdan Başlama” 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 Coding Interview Prep kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. Coding Interview Prep kursu toplamda 4 dersten oluşur.
“Big-O Gösterimine Sıfırdan Başlama” dersinde ne öğreneceğim?
Asimptotik büyümeyi neden önemsediğimizi, sabitleri ve düşük dereceli terimleri nasıl göz ardı edeceğinizi ve Big-O gösterimini bir bakışta nasıl okuyacağınızı anlayın. Coding 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.
Coding Interview Prep öğrenmeye başlamak için deneyim gerekli mi?
Önceden deneyim gerekmez. CoddyKit'te Coding 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 1. dersidir.
“Big-O Gösterimine Sıfırdan Başlama” 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 Coding Interview Prep dersinde kod yazıp çalıştırabilir miyim?
Evet. Her Coding 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
- Big-O Gösterimine Sıfırdan Başlama
- Döngüleri ve İç İçe Döngüleri İnceleme
- Özyineleme ve Özyineleme Ağacı Yöntemi
- Alan Karmaşıklığı ve Ödünleşimler