0Pricing
DSA Interview Prep · Pelajaran

Notasi Big-O dari Dasar

Pahami pentingnya pertumbuhan asimtotik, cara menghilangkan konstanta dan suku berorde lebih rendah, serta cara membaca Big-O sekilas.

Notasi Big-O dari Dasar adalah pelajaran DSA Interview Prep gratis di CoddyKit. Ini adalah pelajaran 1 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar DSA Interview Prep, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus DSA Interview Prep mencakup 4 pelajaran total.

Mengapa Mengukur Efisiensi Algoritma?

Dua program dapat sama-sama benar, tetapi salah satunya selesai dalam sekejap, sedangkan yang lain berjalan selama berjam-jam. Kompleksitas waktu menjelaskan bagaimana waktu berjalan bertambah ketika ukuran input membesar.

# 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]))  # 9

Big-O: Batas Atas Asimtotik

Big-O menjelaskan batas atas terburuk mengenai seberapa cepat biaya bertambah. Triknya adalah menghapus konstanta dan suku yang lebih kecil karena pada skala besar hanya suku dominan yang penting. Lihat kodenya.

# 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^2

Kelas Kompleksitas yang Umum

Dari yang tercepat hingga yang paling lambat: O(1), O(log n), O(n), O(n log n), O(n^2), O(2^n), O(n!). Dengan mengetahui ini, Anda dapat memilih pendekatan yang tepat sebelum menulis satu baris pun.

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 larger

Mengabaikan Konstanta: Mengapa Ini Penting

Menjalankan 5n langkah atau 2n langkah sama-sama O(n) — konstanta bergantung pada perangkat keras, bukan algoritmanya. Big-O menghilangkan konstanta tersebut agar Anda dapat membandingkan pertumbuhan pada dasar yang sama.

# 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 50

Kasus Terbaik, Rata-rata, dan Terburuk

Big-O adalah kasus terburuk; Omega adalah kasus terbaik; Theta adalah batas ketat untuk keduanya. Saat pewawancara menanyakan “kompleksitasnya”, hampir selalu yang dimaksud adalah kasus terburuk.

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))   # -1

O(log n): Membagi Dua Ruang Pencarian

Algoritma disebut O(log n) jika algoritma tersebut membagi dua input pada setiap langkah, seperti pada pencarian biner. Bahkan untuk satu miliar item, algoritma itu hanya memerlukan sekitar 30 langkah — sangat cepat. Lihat kodenya.

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): Batas Bawah Pengurutan

Setiap algoritma pengurutan berbasis perbandingan memerlukan setidaknya O(n log n) pada kasus terburuk — ini adalah batas bawah matematika yang nyata. Jadi, mengurutkan lalu memindai memiliki kompleksitas keseluruhan O(n log n), bukan O(n^2). Kodenya menunjukkan pengurutan gabung.

# 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]

Kompleksitas Teramortisasi

Analisis teramortisasi menghitung rata-rata biaya di banyak operasi. append Python memiliki kompleksitas teramortisasi O(1): biasanya berlangsung seketika, dengan perubahan ukuran O(n) yang jarang terjadi dan biayanya tersebar di seluruh operasi append.

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

Mengenali Kompleksitas dalam Kode

Aturan cepat: hitung perulangan. Satu perulangan adalah O(n), dua perulangan yang bersarang adalah O(n^2), dan perulangan yang membagi dua adalah O(log n). Lintasan independent dijumlahkan melalui add; hanya perulangan nested yang dikalikan. Lihat kodenya.

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

Dasar-dasar Kompleksitas Ruang

Kompleksitas ruang melacak memori tambahan yang digunakan di luar input. Pembalikan secara langsung di tempat adalah O(1); peta hash adalah O(n). Saat menukar waktu dengan ruang, selalu nyatakan keduanya.

# 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]

Membahas Kompleksitas dalam Wawancara

Selalu sampaikan kompleksitas tanpa harus ditanya: “Ini memerlukan waktu O(n log n) dan ruang O(n).” Kemudian tawarkan pilihan yang lebih cepat. Kebiasaan itu menunjukkan tingkat kemahiran yang tinggi.

# 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]

Pemeriksaan Singkat

Pemeriksaan singkat — tunjukkan seberapa banyak pemahaman Anda tentang Big-O dan kelas kompleksitas. Hanya satu pertanyaan, Anda pasti bisa. 🎯

Rangkuman Pelajaran

Rangkuman: Big-O menunjukkan pertumbuhan pada kasus terburuk dengan konstanta yang dihilangkan, Anda telah mengenal kelas-kelas dari O(1) hingga O(n!), dan perulangan independent dijumlahkan sedangkan perulangan yang bersarang dikalikan.

Pertanyaan yang Sering Diajukan

Apakah pelajaran “Notasi Big-O dari Dasar” gratis?

Ya — teks lengkap “Notasi Big-O dari Dasar” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus DSA Interview Prep, upgrade ke CoddyKit PRO. Kursus DSA Interview Prep mencakup 4 pelajaran total.

Apa yang akan aku pelajari di “Notasi Big-O dari Dasar”?

Pahami pentingnya pertumbuhan asimtotik, cara menghilangkan konstanta dan suku berorde lebih rendah, serta cara membaca Big-O sekilas. Kamu berlatih DSA Interview Prep dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.

Apakah aku perlu pengalaman untuk memulai DSA Interview Prep?

Tidak diperlukan pengalaman sebelumnya. DSA Interview Prep di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 1 dari 4.

Berapa lama pelajaran “Notasi Big-O dari Dasar” memakan waktu?

Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.

Bisakah aku menulis dan menjalankan kode dalam pelajaran DSA Interview Prep ini?

Ya. Setiap pelajaran DSA Interview Prep menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.

Semua pelajaran dalam kursus ini

  1. Notasi Big-O dari Dasar
  2. Menganalisis Loop dan Loop Bersarang
  3. Rekursi dan Metode Pohon Rekursi
  4. Kompleksitas Ruang dan Pertukarannya
← Kembali ke DSA Interview Prep