Big O Notation in JavaScript - Lee-hyuna/33-js-concepts-kr GitHub Wiki

원문 좜처: https://medium.com/cesars-tech-insights/big-o-notation-javascript-25c79f50b19b

"Big O Notation"μ΄λž€ 무엇인가?
이것은 κ°œλ°œμžλ“€μ—κ²Œ 맀우 ν”ν•œ λ©΄μ ‘ μ§ˆλ¬Έμž…λ‹ˆλ‹€.
κ°„λ‹¨νžˆ λ§ν•΄μ„œ, μž…λ ₯ μ‹œκ°„μ— 따라 μ•Œκ³ λ¦¬μ¦˜μ΄ μ‹€ν–‰λ˜λŠ” 데 κ±Έλ¦¬λŠ” μ‹œκ°„μ„ μˆ˜ν•™μ μœΌλ‘œ ν‘œν˜„ν•œ 것인데, 보톡 μ΅œμ•…μ˜ 경우 μ‹œλ‚˜λ¦¬μ˜€μ— λŒ€ν•΄ μ΄μ•ΌκΈ°ν•©λ‹ˆλ‹€.

μ‹€μ œλ‘œ, μš°λ¦¬λŠ” Big O Notation을 μ‚¬μš©ν•˜μ—¬ μž…λ ₯ 크기의 변화에 λŒ€μ‘ν•˜λŠ” λ°©μ‹μœΌλ‘œ μ•Œκ³ λ¦¬μ¦˜μ„ λΆ„λ₯˜ν•©λ‹ˆλ‹€.
κ·Έλž˜μ„œ μ¦κ°€μœ¨μ΄ λ™μΌν•œ μ•Œκ³ λ¦¬μ¦˜μ€ λ™μΌν•œ Big O Notation으둜 ν‘œν˜„λ©λ‹ˆλ‹€. ν•¨μˆ˜μ˜ μ„±μž₯λ₯ μ„ ν•¨μˆ˜μ˜ μˆœμ„œλΌκ³ λ„ ν•˜κΈ° λ•Œλ¬Έμ— O자λ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€.

이것을 μ•„λŠ” 것이 μ™œ μ€‘μš”ν• κΉŒμš”? Big Oλ₯Ό μ•Œλ©΄ κ°œλ°œμžκ°€ μ•Œκ³ λ¦¬μ¦˜μ˜ νš¨μœ¨μ„±μ„ μΈμ§€ν•˜κ³  μ„±λŠ₯이 쒋은 μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ„ λ§Œλ“€ 수 μžˆλ„λ‘ λ„μ™€μ€λ‹ˆλ‹€.

일반적으둜 μ•Œκ³ λ¦¬μ¦˜μ˜ 첫 번째 버전이 κ°€μž₯ 효율적인 μ†”λ£¨μ…˜μ΄ μ•„λ‹ˆλΌ κ°€μž₯ λΉ λ₯Έ μ½”λ“œν™” 버전이라고 κ°€μ •ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
ν–₯ν›„ λ²„μ „μ—μ„œλŠ” 더 효율적인 μ†”λ£¨μ…˜μœΌλ‘œ ꡐ체될 κ²ƒμœΌλ‘œ κ°€μ •ν•©λ‹ˆλ‹€. μ΄λŠ” λ―Όμ²©ν•œ 개발, 특히 ν…ŒμŠ€νŠΈ 기반 κ°œλ°œμ—μ„œ 맀우 일반적인 λ°©μ‹μž…λ‹ˆλ‹€.

λ•Œλ‘œλŠ” 더 적은 μ‹œκ°„(문자)을 μ‚¬μš©ν•˜λŠ” λŒ€μ‹ (λ˜λŠ” 더 적은 λ©”λͺ¨λ¦¬μ—) 더 적은 λ©”λͺ¨λ¦¬λ₯Ό μ‚¬μš©ν•˜λŠ” 데 μ΄ˆμ μ„ λ§žμΆ”κΈ°λ₯Ό μ›ν•˜κΈ°λ„ ν•©λ‹ˆλ‹€. 일반적으둜 μ‹œκ°„ μ ˆμ•½κ³Ό 곡간 μ ˆμ•½ 사이에 절좩이 μ΄λ£¨μ–΄μ§‘λ‹ˆλ‹€. 읽기 μ‹œκ°„ μ ˆμ•½κ³Ό λ””μŠ€ν¬ 곡간 μ ˆμ•½ 간에 λ˜λŠ” κ΄€κ³„ν˜•(μ •κ·œν™”λœ) λ°μ΄ν„°λ² μ΄μŠ€μ™€ λΉ„κ΄€κ³„ν˜•(λΉ„μ •κ·œν™”λœ) λ°μ΄ν„°λ² μ΄μŠ€λ₯Ό 비ꡐ할 λ•Œλ„ μ΄λŸ¬ν•œ κ· ν˜•μ„ 확인할 수 μžˆμŠ΅λ‹ˆλ‹€.

이제 κ°€μž₯ 일반적인 μœ ν˜•μ˜ Big O Notations에 λŒ€ν•΄ μ‚΄νŽ΄λ³΄κ² μŠ΅λ‹ˆλ‹€. JavaScript(ECMA6)λ₯Ό μ°Έμ‘° μ–Έμ–΄λ‘œ μ‚¬μš©ν•˜μ§€λ§Œ λ‹€λ₯Έ 언어에도 λ™μΌν•œ 원리가 μ μš©λ©λ‹ˆλ‹€.

λ³€ν•¨μ—†λŠ” μ‹œκ°„μ˜ λŒ€ν•œ μ•Œκ³ λ¦¬μ¦˜

O(1) β€” β€œOrder 1”

ν•˜μ§€λ§Œ 아직 이 μˆœμ„œμ—μ„œλŠ” λ³΅μž‘μ„±(ν•­λͺ© 수)에 관계없이 μ‹œκ°„(문자)이 μΌμ •ν•©λ‹ˆλ‹€.

μœ ν˜• λ˜λŠ” 길이에 관계없이 이미 μ•Œλ €μ§„ λ°°μ—΄ μœ„μΉ˜μ— μžˆλŠ” μš”μ†Œλ₯Ό λ°˜ν™˜ν•˜λŠ” μ•Œκ³ λ¦¬μ¦˜μ—μ„œ 이 정보λ₯Ό λ³Ό 수 μžˆμŠ΅λ‹ˆλ‹€.

예제 μ½”λ“œ:

const getLast = items =>
  items[items.length-1];

μ˜ˆμ‹œ μΌ€μ΄μŠ€:

getLast(['a', 'b', 'c', 'd']); // d (1 iteration)
getLast(['a', 'b', 'c', 'd', 'e', 'f', 'g']);// g(1 iteration)

μ„ ν˜• μ‹œκ°„ μ•Œκ³ λ¦¬μ¦˜

O(N) β€” β€œOrder N”

이 μˆœμ„œμ—μ„œ μ΅œμ•…μ˜ 경우 μ‹œκ°„(문자)은 ν•­λͺ© μˆ˜μ™€ ν•¨κ»˜ μ¦κ°€ν•©λ‹ˆλ‹€. 즉, N μš”μ†Œμ˜ 경우 N 반볡이 ν•„μš”ν•©λ‹ˆλ‹€.

μ˜ˆμ œμ½”λ“œ:

const findIndex = (items, match) => {
  for (let i = 0, total = items.length; i < total; i++)
    if (items[i] == match)
      return i;
   return -1;
};

μ˜ˆμ‹œμΌ€μ΄μŠ€:

const array= ['a', 'b', 'c', 'd'];
findIndex(array, 'a'); // 0  (1 iteration - best case)
findIndex(array, 'd'); // 3  (4 iterations - worst case)
findIndex(array, 'e'); // -1 (4 iterations - worst case)

Quadratic - time μ•Œκ³ λ¦¬μ¦˜

O(N 2 ) β€” β€œOrder N squared”

μ΄λŸ¬ν•œ μ’…λ₯˜μ˜ μˆœμ„œμ˜ 경우 μ΅œμ•…μ˜ 경우 μ‹œκ°„(문자)은 μž…λ ₯ 수의 μ œκ³±μž…λ‹ˆλ‹€. μ‹œκ°„μ€ μž…λ ₯ μˆ˜μ™€ κ΄€λ ¨ν•˜μ—¬ κΈ°ν•˜κΈ‰μˆ˜λ‘œ μ¦κ°€ν•©λ‹ˆλ‹€.

μ˜ˆμ œμ½”λ“œ:

const buildSquareMatrix = items => {
  let matrix = [];
  for (let i = 0, total = items.length; i < total; i++){ 
    matrix[i] = [];
    for (let j = 0, total = items.length; j < total; j++)
      matrix[i].push(items[j]);
  }
  return matrix;
};

μ˜ˆμ œμΌ€μ΄μŠ€:

buildSquareMatrix(['a', 'b', 'c']); 
/* 9 iterations for 3 elements, returns:
[
  ['a', 'b', 'c'],
  ['a', 'b', 'c'],
  ['a', 'b', 'c']
]
/*

둜그 μ‹œκ°„ μ•Œκ³ λ¦¬μ¦˜

O(log n) β€” β€œOrder log N”

search/sort μ•Œκ³ λ¦¬μ¦˜μ˜ 기본이며, λŒ€κ·œλͺ¨ μˆ˜μ§‘μ„ μ²˜λ¦¬ν•  λ•Œ κ°€μž₯ 효율적인 μ ‘κ·Όλ°©μ‹μž…λ‹ˆλ‹€.
ꡬ성 μš”μ†Œλ₯Ό ν•˜λ‚˜μ”© μ‚΄νŽ΄λ³΄λŠ” λŒ€μ‹  데이터λ₯Ό λ©μ–΄λ¦¬λ‘œ λΆ„ν• ν•˜κ³  맀 반볡, 보톡 절반 λ˜λŠ” 둜그 베이슀 2에 λ§Žμ€ 양을 λ‚­λΉ„ν•©λ‹ˆλ‹€.

둜그 베이슀 2λ₯Ό μ‚¬μš©ν•œλ‹€κ³  κ°€μ •ν•  경우, 20개 미만의 λ°˜λ³΅μ„ μ‚¬μš©ν•˜λŠ” 100만 개의 μš”μ†Œ μ§‘ν•©μ—μ„œ νŠΉμ • μš”μ†Œλ₯Ό 찾을 수 μžˆμŠ΅λ‹ˆλ‹€. μˆ˜μ§‘ 크기λ₯Ό 10μ–΅ 개둜 ν™•μž₯ν•˜λ©΄ 30개 미만의 반볡만 ν•„μš”ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

λΉ…λ°μ΄ν„°λŠ” 맀일 더 ν”ν•˜κ²Œ μ‚¬μš©λ˜λ―€λ‘œ μˆ˜μ§‘ 규λͺ¨κ°€ 클수둝 μƒλŒ€μ μœΌλ‘œ νš¨μœ¨μ„±μ΄ 높아지기 λ•Œλ¬Έμ— μ΄λŸ¬ν•œ μ•Œκ³ λ¦¬μ¦˜μ˜ 이점을 μ‰½κ²Œ 확인할 수 μžˆμŠ΅λ‹ˆλ‹€.

이 μ•Œκ³ λ¦¬μ¦˜ 쀑 κ°€μž₯ 널리 μ‚¬μš©λ˜λŠ” μ•Œκ³ λ¦¬μ¦˜μ€ νŠΉμ • μš”μ†Œλ₯Ό μ°Ύκ±°λ‚˜ λͺ©λ‘μ„ 맀우 효율적으둜 μ •λ ¬ν•˜λŠ” 데 μ‚¬μš©ν•  수 μžˆλŠ” Quick sort μ•Œκ³ λ¦¬μ¦˜μž…λ‹ˆλ‹€. 이 μˆœμ„œμ˜ 또 λ‹€λ₯Έ 인기 μžˆλŠ” μ˜ˆλŠ” 병합 μ •λ ¬ μ•Œκ³ λ¦¬μ¦˜μž…λ‹ˆλ‹€. ν–₯ν›„ 기사에 λŒ€ν•œ μ΄λŸ¬ν•œ μ•Œκ³ λ¦¬μ¦˜μ„ μ‚΄νŽ΄λ³΄κ² μŠ΅λ‹ˆλ‹€.

μ˜ˆμ œμ½”λ“œ:

const quickSort = list => {
  if (list.length < 2) 
    return list;
  let pivot = list[0];
  let left  = []; 
  let right = [];
  for (let i = 1, total = list.length; i < total; i++){
    if (list[i] < pivot)
      left.push(list[i]);
    else
      right.push(list[i]);
  }
  return [
    ...quickSort(left), 
    pivot, 
    ...quickSort(right)
  ];
};

μ˜ˆμ œμΌ€μ΄μŠ€:

quickSort( ['q','a','z','w','s','x','e','d','c','r']);
// ["a", "c", "d", "e", "q", "r", "s", "w", "x", "z"]

이것이 κ°€μž₯ 일반적인 μœ ν˜•μ˜ μ•Œκ³ λ¦¬μ¦˜μ„ λ‹€λ£¨λŠ” λ°©λ²•μž…λ‹ˆλ‹€. 검색 및 μ •λ ¬ μ•Œκ³ λ¦¬μ¦˜μ— λŒ€ν•΄ μžμ„Ένžˆ μ½μ–΄λ³΄μ‹œκΈ° λ°”λžλ‹ˆλ‹€.