Post

๐Ÿน 11. Recursion & Dynamic programming

08. ์žฌ๊ท€์™€ ๋™์  ํ”„๋กœ๊ทธ๋ž˜๋ฐ

์žฌ๊ท€์™€ ๊ด€๋ จ๋œ ๋ฌธ์ œ๋“ค์€ ์ƒ๋‹น์ˆ˜๋Š” ํŒจํ„ด์ด ๋น„์Šทํ•˜๋‹ค. ์ฃผ์–ด์ง„ ๋ฌธ์ œ๊ฐ€ ์žฌ๊ท€ ๋ฌธ์ œ์ธ์ง€ ํ™•์ธํ•ด ๋ณด๋Š” ๋ฐฉ๋ฒ•์€, ํ•ด๋‹น ๋ฌธ์ œ๋ฅผ ์ž‘์€ ํฌ๊ธฐ์˜ ๋ฌธ์ œ๋กœ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š”์ง€ ๋ณด๋Š” ๊ฒƒ์ด๋‹ค.

๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฌธ์žฅ์œผ๋กœ ์‹œ์ž‘ํ•˜๋Š” ๋ฌธ์ œ๋Š” ์žฌ๊ท€๋กœ ํ’€๊ธฐ ์ ๋‹นํ•œ ๋ฌธ์ œ์ผ ๊ฐ€๋Šฅ์„ฑ์ด ๋†’๋‹ค.(ํ•ญ์ƒ ๊ทธ๋Ÿฐ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค.)

  • โ€œn๋ฒˆ์งธ โ€ฆ๋ฅผ ๊ณ„์‚ฐํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์„ค๊ณ„ํ•˜๋ผโ€
  • โ€œ์ฒซ n๊ฐœ๋ฅผ ๋‚˜์—ดํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋ผโ€
  • โ€œ๋ชจ๋“  โ€ฆ๋ฅผ ๊ณ„์‚ฐํ•˜๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•˜๋ผโ€

[ ์ ‘๊ทผ๋ฒ• ]

์žฌ๊ท€์  ํ•ด๋ฒ•์€ ๋ถ€๋ถ„๋ฌธ์ œ(subproblem)์— ๋Œ€ํ•œ ํ•ด๋ฒ•์„ ํ†ตํ•ด ์™„์„ฑ๋œ๋‹ค.

๋”ฐ๋ผ์„œ ๋งŽ์€ ๊ฒฝ์šฐ, ๋‹จ์ˆœํžˆ f(n-1)์— ๋Œ€ํ•œ ํ•ด๋‹ต์— ๋ฌด์–ธ๊ฐ€๋ฅผ ๋”ํ•˜๊ฑฐ๋‚˜, ์ œ๊ฑฐํ•˜๊ฑฐ๋‚˜, ์•„๋‹ˆ๋ฉด ๊ทธ ํ•ด๋‹ต์„ ๋ณ€๊ฒฝํ•˜์—ฌ f(n)์„ ๊ณ„์‚ฐํ•ด๋‚ธ๋‹ค. ์•„๋‹ˆ๋ฉด, ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ˜์œผ๋กœ ๋‚˜๋ˆ  ๊ฐ๊ฐ์— ๋Œ€ํ•ด์„œ ๋ฌธ์ œ๋ฅผ ํ‘ผ ๋’ค ์ด ๋‘˜์„ ๋ณ‘ํ•ฉ(merge)ํ•˜๊ธฐ๋„ ํ•œ๋‹ค.

์ฃผ์–ด์ง„ ๋ฌธ์ œ๋ฅผ ๋ถ€๋ถ„๋ฌธ์ œ๋กœ ๋‚˜๋ˆ„๋Š” ๋ฐฉ๋ฒ•๋„ ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ์žˆ๋‹ค. ๊ฐ€์žฅ ํ”ํ•˜๊ฒŒ ์‚ฌ์šฉ๋˜๋Š” ์„ธ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์œผ๋กœ๋Š”

  • ์ƒํ–ฅ์‹(bottom-up)
  • ํ•˜ํ–ฅ์‹(top-down)
  • ๋ฐ˜๋ฐ˜(half-and-half)

์ด ์žˆ๋‹ค.

์ƒํ–ฅ์‹ ์ ‘๊ทผ๋ฒ•

์ƒํ–ฅ์‹ ์ ‘๊ทผ๋ฒ•(bottom-up approach)๋Š” ๊ฐ€์žฅ ์ง๊ด€์ ์ธ ๊ฒฝ์šฐ๊ฐ€ ๋งŽ๋‹ค. ์ด ์ ‘๊ทผ๋ฒ•์€ ์šฐ์„  ๊ฐ„๋‹จํ•œ ๊ฒฝ์šฐ๋“ค์— ๋Œ€ํ•œ ํ’€์ด๋ฒ•์„ ๋ฐœ๊ฒฌํ•˜๋Š” ๊ฒƒ์œผ๋กœ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•œ๋‹ค.

ex) ๋ฆฌ์ŠคํŠธ

์ฒ˜์Œ์—๋Š” ์›์†Œ ํ•˜๋‚˜๋ฅผ ๊ฐ–๋Š” ๋ฆฌ์ŠคํŠธ๋กœ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•œ๋‹ค. ๋‹ค์Œ์—๋Š” ์›์†Œ ๋‘ ๊ฐœ๊ฐ€ ๋“ค์–ด ์žˆ๋Š” ๋ฆฌ์ŠคํŠธ์— ๋Œ€ํ•œ ํ’€์ด๋ฒ•์„ ์ฐพ๊ณ , ๊ทธ ๋‹ค์Œ์—๋Š” ์„ธ ๊ฐœ ์›์†Œ๋ฅผ ๊ฐ–๋Š” ๋ฆฌ์ŠคํŠธ์— ๋Œ€ํ•œ ํ’€์ด๋ฒ•์„ ์ฐพ๋Š”๋‹ค. ์ด๋Ÿฐ ์‹์œผ๋กœ ๊ณ„์†ํ•ด ๋‚˜๊ฐ„๋‹ค.

์ด ์ ‘๊ทผ๋ฒ•์˜ ํ•ต์‹ฌ์€, ์ด์ „์— ํ’€์—ˆ๋˜ ์‚ฌ๋ก€๋ฅผ ํ™•์žฅํ•˜์—ฌ ๋‹ค์Œ ํ’€์ด๋ฅผ ์ฐพ๋Š”๋‹ค๋Š” ์ ์ด๋‹ค.

ํ•˜ํ–ฅ์‹ ์ ‘๊ทผ๋ฒ•

ํ•˜ํ–ฅ์‹ ์ ‘๊ทผ๋ฒ•(top-down approach)๋Š” ๋œ ๋ช…ํ™•ํ•ด์„œ ๋ณต์žกํ•ด ๋ณด์ผ ์ˆ˜ ์žˆ๋‹ค. ํ•˜์ง€๋งŒ ๊ฐ€๋”์€ ์ด ๋ฐฉ๋ฒ•์ด ๋ฌธ์ œ์•  ๋Œ€ํ•ด ์ƒ๊ฐํ•ด ๋ณด๊ธฐ์— ๊ฐ€์žฅ ์ข‹์€ ๋ฐฉ๋ฒ•์ด๊ธฐ๋„ ํ•˜๋‹ค.

์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋“ค์€ ์–ด๋–ป๊ฒŒ ํ•˜๋ฉด N์— ๋Œ€ํ•œ ๋ฌธ์ œ๋ฅผ ๋ถ€๋ถ„ ๋ฌธ์ œ๋กœ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ์„์ง€ ์ƒ๊ฐํ•ด ๋ด์•ผ ํ•œ๋‹ค. ๋‚˜๋‰œ ๋ถ€๋ถ„๋ฌธ์ œ์˜ ๊ฒฝ์šฐ๊ฐ€ ์„œ๋กœ ๊ฒน์น˜์ง€ ์•Š๋„๋ก ์ฃผ์˜ํ•œ๋‹ค.

๋ฐ˜๋ฐ˜ ์ ‘๊ทผ๋ฒ•

๋ฐ์ดํ„ฐ๋ฅผ ์ ˆ๋ฐ˜์œผ๋กœ ๋‚˜๋ˆ„๋Š” ๋ฐฉ๋ฒ•๋„ ์ข…์ข… ์œ ์šฉํ•˜๋‹ค.

ex) ์ด์ง„ ํƒ์ƒ‰

์ •๋ ฌ๋œ ๋ฐฐ์—ด์—์„œ ํŠน์ • ์›์†Œ๋ฅผ ์ฐพ์„ ๋•Œ, ๊ฐ€์žฅ ๋จผ์ € ์™ผ์ชฝ ์ ˆ๋ฐ˜๊ณผ ์˜ค๋ฅธ์ชฝ ์ ˆ๋ฐ˜ ์ค‘ ์–ด๋””๋ฅผ ๋ด์•ผ ํ•˜๋Š”์ง€ ํ™•์ธํ•œ๋‹ค. ์ด์™€ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ์ ˆ๋ฐ˜์”ฉ ์žฌ๊ท€์ ์œผ๋กœ ํƒ์ƒ‰ํ•ด ๋‚˜๊ฐ„๋‹ค.

ex) ๋ณ‘ํ•ฉ ์ •๋ ฌ

๋ฐฐ์—ด ์ ˆ๋ฐ˜์„ ๊ฐ๊ฐ ์ •๋ ฌํ•œ ๋’ค ์ด๋“ค์„ ํ•˜๋‚˜๋กœ ๋ณ‘ํ•ฉํ•œ๋‹ค.

[ ์žฌ๊ท€์  ํ•ด๋ฒ• vs ์ˆœํ™˜์  ํ•ด๋ฒ• ]

  • ์žฌ๊ท€์  ์•Œ๊ณ ๋ฆฌ์ฆ˜

    โ†’ ๊ณต๊ฐ„ ํšจ์œจ์„ฑ์ด ๋‚˜๋น ์งˆ ์ˆ˜ ์žˆ๋‹ค.

    ์žฌ๊ท€ ํ˜ธ์ถœ์ด ํ•œ ๋ฒˆ ๋ฐœ์ƒํ•  ๋•Œ๋งˆ๋‹ค ์Šคํƒ์— ์ƒˆ๋กœ์šด ์ธต(layer)์„ ์ถ”๊ฐ€ํ•ด์•ผ ํ•œ๋‹ค. ์ด๋Š” ์žฌ๊ท€์˜ ๊นŠ์ด๊ฐ€ n์ผ ๋•Œ O(n) ๋งŒํผ์˜ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋œ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค.

์ด๋Ÿฐ ์ด์œ ๋กœ, ์žฌ๊ท€์ (recursive) ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ์ˆœํ™˜์ (iterative)์œผ๋กœ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์ด ๋” ๋‚˜์„ ์ˆ˜ ์žˆ๋‹ค. ๋ชจ๋“  ์žฌ๊ท€์  ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ์ˆœํ™˜์ ์œผ๋กœ ๊ตฌํ˜„๋  ์ˆ˜ ์žˆ์ง€๋งŒ, ์ˆœํ™˜์ ์œผ๋กœ ๊ตฌํ˜„๋œ ์ฝ”๋“œ๋Š” ๋•Œ๋กœ ํ›จ์”ฌ ๋” ๋ณต์žกํ•˜๋‹ค.

[ ๋™์ ๊ณ„ํš๋ฒ• & ๋ฉ”๋ชจ์ด์ œ์ด์…˜ ]

๋™์  ํ”„๋กœ๊ทธ๋ž˜๋ฐ์€ ๊ฑฐ์˜ ๋Œ€๋ถ€๋ถ„ ์žฌ๊ท€์  ์•Œ๊ณ ๋ฆฌ์ฆ˜๊ณผ ๋ฐ˜๋ณต์ ์œผ๋กœ ํ˜ธ์ถœ๋˜๋Š” ๋ถ€๋ถ„๋ฌธ์ œ๋ฅผ ์ฐพ์•„๋‚ด๋Š” ๊ฒƒ์ด ๊ด€๊ฑด์ด๋‹ค. ์ด๋ฅผ ์ฐพ์€ ๋’ค์—๋Š” ๋‚˜์ค‘์„ ์œ„ํ•ด ํ˜„์žฌ ๊ฒฐ๊ณผ๋ฅผ ์บ์‹œ์— ์ €์žฅํ•ด ๋†“์œผ๋ฉด ๋œ๋‹ค.

ํ˜น์€ ์žฌ๊ท€ ํ˜ธ์ถœ์˜ ํŒจํ„ด์„ ์ˆœํ™˜์  ํ˜•ํƒœ๋กœ ๊ตฌํ˜„ํ•  ์ˆ˜๋„ ์žˆ๋‹ค. ๋ฌผ๋ก  ์—ฌ์ „ํžˆ ๊ฒฐ๊ณผ๋ฅผ โ€˜์บ์‹œโ€™์— ์ €์žฅํ•ด์•ผ ํ•œ๋‹ค.

  • ๋ฉ”๋ชจ์ด์ œ์ด์…˜(memoization) : ํ•˜ํ–ฅ์‹ ๋™์  ํ”„๋กœ๊ทธ๋ž˜๋ฐ
  • ๋™์  ํ”„๋กœ๊ทธ๋ž˜๋ฐ : ์ƒํ–ฅ์‹ ์ ‘๊ทผ๋ฒ•

๋™์  ํ”„๋กœ๊ทธ๋ž˜๋ฐ์˜ ๊ฐ€์žฅ ๊ฐ„๋‹จํ•œ ์˜ˆ์‹œ๋Š” n๋ฒˆ์งธ ํ”ผ๋ณด๋‚˜์น˜ ์ˆ˜(Fibonacci number)๋ฅผ ์ฐพ๋Š” ๊ฒƒ์ด๋‹ค. ์ด๋Ÿฐ ๋ฌธ์ œ๋ฅผ ํ’€ ๋•Œ๋Š” ์ผ๋ฐ˜์ ์ธ ์žฌ๊ท€๋กœ ๊ตฌํ˜„ํ•œ ๋’ค ์บ์‹œ ๋ถ€๋ถ„์„ ๋‚˜์ค‘์— ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

ํ”ผ๋ณด๋‚˜์น˜ ์ˆ˜์—ด

ํ”ผ๋ณด๋‚˜์น˜ ์ˆ˜๋ฅผ ์ฐพ๋Š” ๋ฐฉ๋ฒ•

๋ฐฉ๋ฒ• #1: ์žฌ๊ท€

1
2
3
4
5
int fibonacci(int i) {
    if (i == 0) return 0;
    if (i == 1) return 1;
    return fibonacci(i - 1) + fibonacci(i - 2);
}

์ด ํ•จ์ˆ˜์˜ ์ˆ˜ํ–‰ ์‹œ๊ฐ„์„ ๊ณ ๋ คํ•  ๋•Œ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋‹ค๋ฅธ ์žฌ๊ท€ ๋ฌธ์ œ๋ฅผ ํ’€ ๋•Œ ํ˜ธ์ถœ๋˜๋Š” ๊ฒฝ๋กœ๋ฅผ ํŠธ๋ฆฌ๋กœ ๊ทธ๋ ค๋ณด๋ฉด ๋„์›€์ด ๋œ๋‹ค.

ํŠธ๋ฆฌ์˜ ๋ง๋‹จ ๋…ธ๋“œ๋Š” ๋ชจ๋‘ ๊ธฐ๋ณธ ๊ฒฝ์šฐ(base case)์ธ fib(1) ์•„๋‹ˆ๋ฉด fib(0)์ธ ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค. ๊ฐ ํ˜ธ์ถœ์— ์†Œ์š”๋˜๋Š” ์‹œ๊ฐ„์ด O(1) ์ด๋ฏ€๋กœ ํŠธ๋ฆฌ์˜ ์ „์ฒด ๋…ธ๋“œ์˜ ๊ฐœ์ˆ˜์™€ ์ˆ˜ํ–‰ ์‹œ๊ฐ„์€ ๊ฐ™๋‹ค. ๋”ฐ๋ผ์„œ ์ด ํ˜ธ์ถœ ํšŸ์ˆ˜๊ฐ€ ์ˆ˜ํ–‰ ์‹œ๊ฐ„์ด ๋œ๋‹ค.

๊ธฐ๋ณธ ๊ฒฝ์šฐ(๋ง๋‹จ ๋…ธ๋“œ)์— ๋„๋‹ฌํ•˜๊ธฐ ์ „๊นŒ์ง€์˜ ๊ฐ ๋…ธ๋“œ๋Š” ๋‘ ๊ฐœ์˜ ์ž์‹ ๋…ธ๋“œ๋ฅผ ๊ฐ–๊ณ  ์žˆ๋‹ค. ์ด ์ž์‹ ๋…ธ๋“œ ๋˜ํ•œ ๋‘ ๊ฐœ์˜ ์ž์‹ ๋…ธ๋“œ๋ฅผ ๊ฐ–๊ณ  ์žˆ๊ณ (์ฆ‰, ๋„ค ๊ฐœ์˜ ์†์ž ๋…ธ๋“œ๊ฐ€ ์žˆ๋Š” ์…ˆ์ด๋‹ค), ์ด ์†์ž ๋…ธ๋“œ๋“ค๋„ ๊ฐ๊ฐ ๋‘ ๊ฐœ์˜ ์ž์‹ ๋…ธ๋“œ๋ฅผ ๊ฐ–๊ณ  ์žˆ๋‹ค.

์ด๋ฅผ n๋ฒˆ ๋ฐ˜๋ณตํ•˜๋ฉด ๋Œ€๋žต $O(2^n)$๊ฐœ์˜ ๋…ธ๋“œ๋ฅผ ๊ฐ–๊ฒŒ ๋œ๋‹ค. ๋”ฐ๋ผ์„œ ์ˆ˜ํ–‰ ์‹œ๊ฐ„์€ ๋Œ€์ถฉ $O(2^n)$์ด ๋œ๋‹ค.

์‹ค์ œ๋ก  $O(2^n)$๋ณด๋‹ค ๋น ๋ฅด๋‹ค. ์œ„ ๊ทธ๋ฆผ์„ ๋ณด๋ฉด (๋ง๋‹จ ๋…ธ๋“œ์™€ ๋ง๋‹จ ๋…ธ๋“œ ๋ฐ”๋กœ ์œ„๋Š” ์ œ์™ธํ•˜๊ณ ) ์˜ค๋ฅธ์ชฝ ๋ถ€๋ถ„ํŠธ๋ฆฌ์˜ ํฌ๊ธฐ๊ฐ€ ์™ผ์ชฝ ๋ถ€๋ถ„ํŠธ๋ฆฌ์˜ ํฌ๊ธฐ๋ณด๋‹ค ํ•ญ์ƒ ์ž‘๋‹ค๋Š” ์‚ฌ์‹ค์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค. ๋งŒ์•ฝ ์ด ๋‘˜์˜ ํฌ๊ธฐ๊ฐ€ ๊ฐ™๋‹ค๋ฉด ์ˆ˜ํ–‰ ์‹œ๊ฐ„์€ $O(2^n)$์ด ๋  ๊ฒƒ์ด๋‹ค.

ํ•˜์ง€๋งŒ ์–‘์ชฝ์˜ ํฌ๊ธฐ๊ฐ€ ๊ฐ™์ง€ ์•Š์œผ๋ฏ€๋กœ, ์‹ค์ œ ์ˆ˜ํ–‰ ์‹œ๊ฐ„์€ $O(1.6^n)$์— ๊ฐ€๊น๋‹ค. big-O ํ‘œ๊ธฐ๋ฒ•์€ ์ˆ˜ํ–‰ ์‹œ๊ฐ„์˜ ์ƒํ•œ์„ ์˜๋ฏธํ•˜๋Š” ๊ฒƒ์ด๋ฏ€๋กœ $O(2^n)$๋„ ๊ธฐ์ˆ ์ ์œผ๋กœ ์˜ณ์€ ํ‘œํ˜„๋ฒ•์ด๊ธด ํ•˜๋‹ค. ์–ด์จŒ๋“  ์—ฌ์ „ํžˆ ์ˆ˜ํ–‰ ์‹œ๊ฐ„์€ ์ง€์ˆ˜ ์‹œ๊ฐ„์ด๋‹ค.

(์ง€์ˆ˜ ์‹œ๊ฐ„์€ ์ˆ˜ํ–‰ ์‹œ๊ฐ„์ด ๊ธฐํ•˜๊ธ‰์ˆ˜์ ์œผ๋กœ ์ฆ๊ฐ€ํ•œ๋‹ค.)

์ตœ์ ํ™” ๋ฐฉ๋ฒ•์„ ์ฐพ์•„์•ผ ํ•œ๋‹ค.

๋ฐฉ๋ฒ• #2: ํ•˜ํ–ฅ์‹ ๋™์  ํ”„๋กœ๊ทธ๋ž˜๋ฐ(๋ฉ”๋ชจ์ด์ œ์ด์…˜)

์žฌ๊ท€ ํŠธ๋ฆฌ์—์„œ ๋งŽ์€ ๋…ธ๋“œ๋“ค์ด ์ค‘๋ณต๋˜์–ด ํ˜ธ์ถœ๋œ๋‹ค. ์ด๋“ค์ด ํ˜ธ์ถœ๋  ๋•Œ๋งˆ๋‹ค ๋‹ค์‹œ ๊ณ„์‚ฐํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค.

์‚ฌ์‹ค, ์šฐ๋ฆฌ๊ฐ€ fib(n)์„ ํ˜ธ์ถœํ–ˆ์„ ๋•Œ, fib์ด ํƒ์ƒ‰ํ•  ๊ฒฝ์šฐ์˜ ์ˆ˜๊ฐ€ O(n)์ด๋ฏ€๋กœ fib ํ•จ์ˆ˜๋ฅผ O(n)๋ฒˆ ์ด์ƒ ํ˜ธ์ถœํ•˜๋ฉด ์•ˆ๋œ๋‹ค. ๋งค๋ฒˆ fib(i)๋ฅผ ๊ณ„์‚ฐํ•  ๋•Œ๋งˆ๋‹ค ์ด ๊ฒฐ๊ณผ๋ฅผ ์บ์‹œ์— ์ €์žฅํ•˜๊ณ  ๋‚˜์ค‘์—๋Š” ์ €์žฅ๋œ ๊ฐ’์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค. ๋ฐ”๋กœ ์ด๊ฒŒ ๋ฉ”๋ชจ์ด์ œ์ด์…˜(memoization)์ด๋‹ค.

์ด์ „์˜ ์ฝ”๋“œ๋ฅผ ์•ฝ๊ฐ„ ๊ณ ์ณ O(N) ์‹œ๊ฐ„์— ๋Œ์•„๊ฐ€๊ฒŒ๋” ๋งŒ๋“ ๋‹ค. ์žฌ๊ท€ ํ˜ธ์ถœ ์‚ฌ์ด์— fibonacci(i)์˜ ๊ฒฐ๊ณผ๋ฅผ ์บ์‹œ์— ์ €์žฅํ•˜๋Š” ๋ถ€๋ถ„๋งŒ ์ถ”๊ฐ€ํ•œ๋‹ค.

1
2
3
4
5
6
7
8
9
10
11
int fibonacci(int n) {
    return fibonacci(n, new int[n + 1]);
}

int fibonacci(int i, int[] memo) {
    if (i == 0 || i == 1) return i;
    if (memo[i] == 0) {
        memo[i] = fibonacci(i - 1, memo) + fibonacci(i - 2, memo);
    }
    return memo[i];
}

์ผ๋ฐ˜์ ์ธ ์ปดํ“จํ„ฐ์—์„œ ์ด์ „์˜ ์žฌ๊ท€ ํ•จ์ˆ˜ ์ฝ”๋“œ๋ฅผ ๋Œ๋ ค๋ณด๋ฉด 50๋ฒˆ์งธ ํ”ผ๋ณด๋‚˜์น˜ ์ˆ˜๋ฅผ ์ฐพ๋Š” ๋ฐ 1๋ถ„ ์ด์ƒ ๊ฑธ๋ฆฐ๋‹ค. ํ•˜์ง€๋งŒ ๋™์  ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ์‚ฌ์šฉํ•˜๋ฉด 10,000๋ฒˆ์งธ ํ”ผ๋ณด๋‚˜์น˜ ์ˆ˜์—ด์„ ์ฐพ๋Š” ๋ฐ ๋ฐ€๋ฆฌ์ดˆ(millisecond)๋„ ๊ฑธ๋ฆฌ์ง€ ์•Š๋Š”๋‹ค(๋ฌผ๋ก  ์œ„์˜ ์ฝ”๋“œ๋ฅผ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•˜๋ฉด 10,000๋ฒˆ์ด ๋˜๊ธฐ๋„ ์ „์— int ์ž๋ฃŒํ˜• ๋•Œ๋ฌธ์— ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ๊ฐ€ ๋ฐœ์ƒํ•  ๊ฒƒ์ด๋‹ค)

์žฌ๊ท€ ํŠธ๋ฆฌ๋ฅผ ๊ทธ๋ ค๋ณด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.(์‚ฌ๊ฐํ˜•์œผ๋กœ ํ‘œ์‹œ๋œ ๋ถ€๋ถ„์€ ์บ์‹œ๊ฐ’์„ ๊ทธ๋Œ€๋กœ ๋ฐ˜ํ™˜ํ•œ ๊ฒฝ์šฐ๋ฅผ ๋‚˜ํƒ€๋‚ธ๋‹ค)

์ด ํŠธ๋ฆฌ์—์„œ ๊ฐ ๋…ธ๋“œ์˜ ์ž์‹ ๋…ธ๋“œ๋Š” ํ•œ ๊ฐœ์ด๋ฏ€๋กœ, ๋ชจ๋“  ๋…ธ๋“œ์˜ ๊ฐœ์ˆ˜๋Š” ๋Œ€๋žต 2n๊ฐœ๊ฐ€ ๋œ๋‹ค. ๋”ฐ๋ผ์„œ ์ˆ˜ํ–‰ ์‹œ๊ฐ„์€ O(n)์ด๋‹ค.

๋ฐฉ๋ฒ• #3: ์ƒํ–ฅ์‹ ๋™์  ํ”„๋กœ๊ทธ๋ž˜๋ฐ

์žฌ๊ท€์ ์ธ ๋ฉ”๋ชจ์ด์ œ์ด์…˜์œผ๋กœ ์ ‘๊ทผํ•˜๋˜ ๊ทธ๊ฒƒ์„ ๋’ค์ง‘๋Š”๋‹ค๊ณ  ์ƒ๊ฐํ•ด๋ณด์ž.

๋จผ์ €, ์ดˆ๊ธฐ ์‚ฌ๋ก€(base case)์ธ fib(1)๊ณผ fib(0)์„ ๊ณ„์‚ฐํ•œ๋‹ค. ๊ทธ ๋’ค, ์ด ๋‘˜์„ ์ด์šฉํ•ด fib(2)๋ฅผ ๊ณ„์‚ฐํ•˜๊ณ , ์ฐจ๋ก€๋กœ fib(3), fib(4) ๋“ฑ์„ ์ด์ „์˜ ๊ฒฐ๊ณผ๋ฅผ ์ด์šฉํ•ด ๊ณ„์‚ฐํ•œ๋‹ค.

1
2
3
4
5
6
7
8
9
10
11
int fibonacci(int n) {
    if (n == 0) return 0;
    else if (n == 1) return 1;
    int[] memo = new int[n];
    memo[0] = 0;
    memo[1] = 1;
    for (int i = 2; i < n; i++) {
        memo[i] = memo[i - 1] + memo[i - 2];
    }
    return memo[n - 1] + memo[n - 2];
}

memo[i]๋Š” memo[i+1]๊ณผ memo[i+2]๋ฅผ ๊ณ„์‚ฐํ•  ๋•Œ๋งŒ ์‚ฌ์šฉ๋  ๋ฟ, ๊ทธ ๋’ค์—๋Š” ์ „ํ˜€ ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š”๋‹ค. ๋”ฐ๋ผ์„œ memo ํ…Œ์ด๋ธ” ๋ง๊ณ  ๋ณ€์ˆ˜ ๋ช‡ ๊ฐœ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ํ’€ ์ˆ˜๋„ ์žˆ๋‹ค.

1
2
3
4
5
6
7
8
9
10
11
int fibonacci(int n) {
    if (n == 0) return 0;
    int a = 0;
    int b = 1;
    for (int i = 2; i < n; i++) {
        int c = a + b;
        a = b;
        b = c;
    }
    return a + b;
}

์œ„ ์ฝ”๋“œ๋Š” ๋‹จ์ˆœํžˆ ํ”ผ๋ณด๋‚˜์น˜ ์ˆ˜์—ด์˜ ๋งˆ์ง€๋ง‰ ์ˆซ์ž ๋‘ ๊ฐœ๋ฅผ a์™€ b ๋ณ€์ˆ˜์— ์ €์žฅํ•˜๋„๋ก ๋ฐ”๊พผ ๊ฒฐ๊ณผ๋‹ค. ๋ฃจํ”„์˜ ๊ฐ ๋‹จ๊ณ„์—์„œ๋Š” ๋‹ค์Œ ๊ฐ’ (c = a + b)์„ ๊ณ„์‚ฐํ•œ ๋’ค (b, c = a + b)์˜ ๊ฐ’์„ (a, b)๋กœ ์˜ฎ๊ธฐ๋Š” ์ผ์„ ์ˆ˜ํ–‰ํ–ˆ๋‹ค.

This post is licensed under CC BY 4.0 by the author.