개발 곡뢀/μ•Œκ³ λ¦¬μ¦˜

λΉ…μ˜€(Big-O) ν‘œκΈ°λ²•

κ°€μš€μ΄ 2024. 1. 11. 01:05

λΉ…μ˜€(Big-O)λž€,

μ½”λ“œμ—μ„œ 데이터가 λŠ˜μ–΄λ‚  λ•Œ μ•Œκ³ λ¦¬μ¦˜μ˜ μ„±λŠ₯을 ν‘œκΈ°ν•˜λŠ” 방법이닀.

 

λ‹¨μˆœνžˆ μ½”λ“œκ°€ 'μ’‹λ‹€', 'λ‚˜μ˜λ‹€'둜 ν‘œν˜„ν•˜λŠ” 것이 μ•„λ‹Œ 숫자둜 μ½”λ“œμ˜ μ„±λŠ₯을 ν‘œκΈ°ν•˜κΈ° μœ„ν•΄ λΉ…μ˜€ ν‘œκΈ°λ²•μ„ μ‚¬μš©ν•œλ‹€.

μž…λ ₯의 크기와 μ‹€ν–‰ μ‹œκ°„κ³Όμ˜ 관계라고 ν•  수 μžˆλ‹€.

 

 

 

데이터 μ›μ†Œκ°€ N개일 λ•Œ μ•Œκ³ λ¦¬μ¦˜μ€ λͺ‡ 단계가 ν•„μš”ν• κΉŒ?

좜처: Desmos

 

 

O(1)κ³Ό O(N)

μœ„μ˜ κ·Έλž˜ν”„μ—μ„œ x좕을 데이터 수둜 봀을 경우, O(N)의 κ·Έλž˜ν”„λŠ” λ°μ΄ν„°μ˜ μˆ˜κ°€ λŠ˜μ–΄λ‚ μˆ˜λ‘ μ•Œκ³ λ¦¬μ¦˜ 단계도 λŠ˜μ–΄λ‚œλ‹€.

즉, 데이터가 1000κ°œκ°€ 되면 μ•Œκ³ λ¦¬μ¦˜λ„ 1000단계가 κ±Έλ¦°λ‹€.

 

O(1)의 κ·Έλž˜ν”„λ₯Ό 보면 데이터가 1κ°œμ΄κ±°λ‚˜ 1000κ°œμ΄κ±°λ‚˜ μ•Œκ³ λ¦¬μ¦˜μ€ 항상 100단계가 κ±Έλ¦°λ‹€.

데이터가 100개 미만일 κ²½μš°μ—” O(N)이 λΉ λ₯Ό 수 μžˆκ² μ§€λ§Œ, κ·Έ μ΄μƒμœΌλ‘œ λ„˜μ–΄κ°€λ©΄ O(N)의 μ•Œκ³ λ¦¬μ¦˜μ΄ 훨씬 λ§Žμ€ 단계λ₯Ό 거쳐야 ν•œλ‹€λŠ” 것을 μ•Œ 수 μžˆλ‹€.

 

O(100)이 μ•„λ‹Œ O(1)둜 ν‘œκΈ°ν•˜λŠ” μ΄μœ λŠ” 데이터가 λŠ˜μ–΄λ‚  λ•Œ 단계 μˆ˜κ°€ μ–΄λ–»κ²Œ μ¦κ°€ν•˜λŠ”μ§€λ₯Ό μ„€λͺ…ν•˜λŠ” 것이 λΉ… 였이기 λ•Œλ¬Έμ΄λ‹€.

100단계λ₯Ό ν•˜λ˜, 1단계λ₯Ό ν•˜λ˜ 데이터 증가에 영ν–₯을 λ°›μ§€ μ•ŠκΈ° λ•Œλ¬Έμ— 본질적으둜 같은 μ•Œκ³ λ¦¬μ¦˜μ΄λ‹€.

 

  • O(N) μ•Œκ³ λ¦¬μ¦˜ μ˜ˆμ‹œ
function logAtLeast5(n) {
  for(let i=1; i<=Math.max(5,n); i++) {
    console.log(i)
  }
}

 

μœ„ μ½”λ“œλŠ” 인자둜 5μ΄ν•˜μ˜ 값을 받을 경우 μ½”λ“œκ°€ 총 5번 싀행이 되며, κ·Έ μ΄μƒμ˜ 값을 인자둜 λ°›μœΌλ©΄ μ½”λ“œκ°€ n번 μ‹€ν–‰ν•˜κ²Œ λ˜λŠ” ν•¨μˆ˜μ΄λ‹€.

λ”°λΌμ„œ O(N)인 μ•Œκ³ λ¦¬μ¦˜μ΄λΌ ν•  수 μžˆλ‹€.

 

  • O(1) μ•Œκ³ λ¦¬μ¦˜ μ˜ˆμ‹œ
function logAtMost5(n) {
  for(let i=1; i<=Math.min(5,n); i++) {
    console.log(i)
  }
}

 

μœ„ μ½”λ“œλŠ” 인자둜 5μ΄μƒμ˜ 값을 받아도 항상 5번만 μ‹€ν–‰λœλ‹€. λ”°λΌμ„œ μœ„ μ•Œκ³ λ¦¬μ¦˜μ€ O(1)의 μ„±λŠ₯을 κ°€μ§„λ‹€.

 

 

객체와 λ°°μ—΄μ˜ μ•Œκ³ λ¦¬μ¦˜ μ„±λŠ₯ 평가

: 객체와 배열은 μ•Œκ³ λ¦¬μ¦˜ 문제λ₯Ό ν•΄κ²°ν•  λ•Œ κ°€μž₯ 많이 μ‚¬μš©ν•˜λŠ” μžλ£Œκ΅¬μ‘°μ΄λ‹€.

λ”°λΌμ„œ, μ•Œκ³ λ¦¬μ¦˜ 문제λ₯Ό 효율적으둜 ν•΄κ²°ν•˜κΈ° μœ„ν•΄ 객체/배열을 μ ‘κ·Όν•˜κ±°λ‚˜ μž…λ ₯, 제거 λ“±μ˜ 연산을 μˆ˜ν–‰ν•  λ•Œμ˜ μ•Œκ³ λ¦¬μ¦˜μ˜ μ„±λŠ₯이 μ–΄λ–»κ²Œ λ˜λŠ”μ§€ νŒŒμ•…ν•  ν•„μš”κ°€ μžˆλ‹€.

 

객체

κ°μ²΄λŠ” 정렬이 ν•„μš”κ°€ μ—†κ³ , λΉ λ₯Έ μ ‘κ·Όκ³Ό μž…λ ₯/제거λ₯Ό 원할 λ•Œ μ‚¬μš©ν•œλ‹€.

  • μ ‘κ·Ό O(1)
    • hasOwnProperty
  • 탐색 O(N)
    • Object.keys
    • Object.values
    • Object.entries
  • μž…λ ₯/제거 O(1)

 

λ°°μ—΄

배열은 정렬이 ν•„μš”ν•œ μžλ£Œκ΅¬μ‘°μ΄λ‹€.

  • μ ‘κ·Ό O(1)
    • λ°°μ—΄ index둜 μ ‘κ·Ό
  • μž…λ ₯/제거
    • push/pop λ©”μ„œλ“œ ➑️ O(1)
    • 맨 μ•žμ— μΆ”κ°€/μ‚­μ œν•˜λŠ” unshift/shift λ©”μ„œλ“œ ➑️ O(N)
  • 탐색 O(N)
    • indexOf, findIndex...
  • κ·Έ μ™Έ,
    • concat ➑️ O(N)
    • slice, splice ➑️ O(N)
    • sort ➑️ O(NlogN)

 

 

 

λΉ…μ˜€ ν‘œκΈ° 방법

  • μƒμˆ˜λŠ” λ¬΄μ‹œν•œλ‹€.

좜처: Desmos

: μƒμˆ˜ 값은 μ•Œκ³ λ¦¬μ¦˜ 평가 단계에 영ν–₯을 거의 μ£Όμ§€ μ•ŠλŠ”λ‹€.

 

  • μ΅œκ³ μ°¨ν•­λ§Œ 남겨두고 μ΅œκ³ μ°¨ν•­μ˜ κ³„μˆ˜λ„ λ¬΄μ‹œν•œλ‹€.

좜처: Desmos

: 데이터가 λ§Žμ•„μ§ˆμˆ˜λ‘ μ•Œκ³ λ¦¬μ¦˜ 평가에 영ν–₯을 μ£Όμ§€ μ•ŠκΈ° λ•Œλ¬Έμ— λ¬΄μ‹œν•œλ‹€.

 

 

 

O(logN)

데이터가 두 배둜 증가할 λ•Œλ§ˆλ‹€ ν•œ 단계씩 λŠ˜μ–΄λ‚˜λŠ” μ•Œκ³ λ¦¬μ¦˜

 

둜그(log)λž€, μ§€μˆ˜μ™€ μ—­μ˜ 관계이닀.

 

좜처: mathurl

 

2λ₯Ό λͺ‡ 번 κ³±ν•΄μ•Ό 8을 얻을 수 μžˆλŠ”μ§€λ₯Ό λœ»ν•œλ‹€. 총 3λ²ˆμ΄λ―€λ‘œ 3이 λ‚˜μ˜¨λ‹€.

λ‹€μ‹œ λ§ν•΄μ„œ, 8을 1이 될 λ•ŒκΉŒμ§€ 계속 2둜 λ‚˜λˆ΄μ„ λ•Œ 총 3번이 κ±Έλ¦°λ‹€λŠ” μ˜λ―Έμ΄λ‹€.

 

좜처: mathurl

 

밑이 2인 λ‘œκ·ΈλŠ” μƒλž΅ν•΄μ„œ ν‘œν˜„ν•  수 μžˆλ‹€.

 

μ΄λŸ¬ν•œ 둜그의 μˆ˜μ‹μ— μ˜ν•΄ O(logN)은 μ›μ†Œκ°€ ν•˜λ‚˜κ°€ 될 λ•ŒκΉŒμ§€ 데이터 μ›μ†Œλ₯Ό κ³„μ†ν•΄μ„œ 반으둜 μ€„μ΄λŠ” 만큼의 단계 μˆ˜κ°€ κ±Έλ¦°λ‹€λŠ” λœ»μ΄λ‹€.

logN의 μ„±λŠ₯을 κ°–λŠ” λŒ€ν‘œμ μΈ μ•Œκ³ λ¦¬μ¦˜μœΌλ‘œ 탐색 μ•Œκ³ λ¦¬μ¦˜ 쀑에 이진 탐색이 μžˆλ‹€.

 

 

 

 

λΉ…μ˜€ ν‘œκΈ°λ²• μ’…λ₯˜

 

 

 

λΉ…μ˜€λ₯Ό μ‰½κ²Œ 계산할 수 μžˆλŠ” κ·œμΉ™

  • μ‚°μˆ˜λŠ” μƒμˆ˜ (Nκ³Ό 관련이 μ—†λ‹€.)
  • 인덱슀λ₯Ό μ‚¬μš©ν•΄ λ°°μ—΄μ˜ μ•„μ΄ν…œμ„ μ°ΎλŠ” 것과 ν‚€λ₯Ό μ•Œκ³  κ°μ²΄μ—μ„œ 값을 μ°ΎλŠ” 것 λͺ¨λ‘ μƒμˆ˜ μ‹œκ°„μ΄ κ±Έλ¦°λ‹€.
  • forλŠ” λ£¨ν”„μ˜ 길이*루프 μ•ˆμ˜ μ—°μ‚°μœΌλ‘œ κ³„μ‚°ν•œλ‹€. (루프 μ•ˆμ— 또 루프가 μžˆλŠ” 쀑첩 루프일 경우 N*N이 됨)