diff --git "a/_posts/coding-interview-univ/11.-Recursion-&-Dynamic-programming/2023-12-31-\354\261\204\354\212\271\355\235\254-11.-Recursion-&-Dynamic-programming.md" "b/_posts/coding-interview-univ/11.-Recursion-&-Dynamic-programming/2023-12-31-\354\261\204\354\212\271\355\235\254-11.-Recursion-&-Dynamic-programming.md" new file mode 100644 index 0000000..d706afa --- /dev/null +++ "b/_posts/coding-interview-univ/11.-Recursion-&-Dynamic-programming/2023-12-31-\354\261\204\354\212\271\355\235\254-11.-Recursion-&-Dynamic-programming.md" @@ -0,0 +1,191 @@ +--- +title: ๐Ÿน 11. Recursion & Dynamic programming +author: chaeshee0908 +date: 2023-12-27 23:00:00 +09:00 +categories: [์ฝ”๋”ฉ ์ธํ„ฐ๋ทฐ ๋Œ€ํ•™, 11. Recursion & Dynamic programming] +tags: [์ฝ”๋”ฉ ์ธํ„ฐ๋ทฐ ๋Œ€ํ•™, ์•Œ๊ณ ๋ฆฌ์ฆ˜, 11์ฃผ์ฐจ, ์ฑ„์Šนํฌ] +render_with_liquid: false +math: true +--- + +# 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: ์žฌ๊ท€ + +```java +int fibonacci(int i) { + if (i == 0) return 0; + if (i == 1) return 1; + return fibonacci(i - 1) + fibonacci(i - 2); +} +``` + +์ด ํ•จ์ˆ˜์˜ ์ˆ˜ํ–‰ ์‹œ๊ฐ„์„ ๊ณ ๋ คํ•  ๋•Œ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋‹ค๋ฅธ ์žฌ๊ท€ ๋ฌธ์ œ๋ฅผ ํ’€ ๋•Œ ํ˜ธ์ถœ๋˜๋Š” ๊ฒฝ๋กœ๋ฅผ ํŠธ๋ฆฌ๋กœ ๊ทธ๋ ค๋ณด๋ฉด ๋„์›€์ด ๋œ๋‹ค. + +![](/assets/img/chaeshee0908/coding-interview-univ/11.-Recursion-&-Dynamic-programming/1.png){: width="600" } + +ํŠธ๋ฆฌ์˜ ๋ง๋‹จ ๋…ธ๋“œ๋Š” ๋ชจ๋‘ ๊ธฐ๋ณธ ๊ฒฝ์šฐ(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)$๋„ ๊ธฐ์ˆ ์ ์œผ๋กœ ์˜ณ์€ ํ‘œํ˜„๋ฒ•์ด๊ธด ํ•˜๋‹ค. ์–ด์จŒ๋“  ์—ฌ์ „ํžˆ ์ˆ˜ํ–‰ ์‹œ๊ฐ„์€ **์ง€์ˆ˜ ์‹œ๊ฐ„**์ด๋‹ค. + +(์ง€์ˆ˜ ์‹œ๊ฐ„์€ ์ˆ˜ํ–‰ ์‹œ๊ฐ„์ด ๊ธฐํ•˜๊ธ‰์ˆ˜์ ์œผ๋กœ ์ฆ๊ฐ€ํ•œ๋‹ค.) + +![](/assets/img/chaeshee0908/coding-interview-univ/11.-Recursion-&-Dynamic-programming/2.png){: width="350" } + +์ตœ์ ํ™” ๋ฐฉ๋ฒ•์„ ์ฐพ์•„์•ผ ํ•œ๋‹ค. + +### ๋ฐฉ๋ฒ• #2: ํ•˜ํ–ฅ์‹ ๋™์  ํ”„๋กœ๊ทธ๋ž˜๋ฐ(๋ฉ”๋ชจ์ด์ œ์ด์…˜) + +์žฌ๊ท€ ํŠธ๋ฆฌ์—์„œ ๋งŽ์€ ๋…ธ๋“œ๋“ค์ด ์ค‘๋ณต๋˜์–ด ํ˜ธ์ถœ๋œ๋‹ค. ์ด๋“ค์ด ํ˜ธ์ถœ๋  ๋•Œ๋งˆ๋‹ค ๋‹ค์‹œ ๊ณ„์‚ฐํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค. + +์‚ฌ์‹ค, ์šฐ๋ฆฌ๊ฐ€ fib(n)์„ ํ˜ธ์ถœํ–ˆ์„ ๋•Œ, fib์ด ํƒ์ƒ‰ํ•  ๊ฒฝ์šฐ์˜ ์ˆ˜๊ฐ€ O(n)์ด๋ฏ€๋กœ fib ํ•จ์ˆ˜๋ฅผ O(n)๋ฒˆ ์ด์ƒ ํ˜ธ์ถœํ•˜๋ฉด ์•ˆ๋œ๋‹ค. ๋งค๋ฒˆ fib(i)๋ฅผ ๊ณ„์‚ฐํ•  ๋•Œ๋งˆ๋‹ค ์ด ๊ฒฐ๊ณผ๋ฅผ ์บ์‹œ์— ์ €์žฅํ•˜๊ณ  ๋‚˜์ค‘์—๋Š” ์ €์žฅ๋œ ๊ฐ’์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค. ๋ฐ”๋กœ ์ด๊ฒŒ ๋ฉ”๋ชจ์ด์ œ์ด์…˜(memoization)์ด๋‹ค. + +์ด์ „์˜ ์ฝ”๋“œ๋ฅผ ์•ฝ๊ฐ„ ๊ณ ์ณ O(N) ์‹œ๊ฐ„์— ๋Œ์•„๊ฐ€๊ฒŒ๋” ๋งŒ๋“ ๋‹ค. ์žฌ๊ท€ ํ˜ธ์ถœ ์‚ฌ์ด์— fibonacci(i)์˜ ๊ฒฐ๊ณผ๋ฅผ ์บ์‹œ์— ์ €์žฅํ•˜๋Š” ๋ถ€๋ถ„๋งŒ ์ถ”๊ฐ€ํ•œ๋‹ค. + +```java +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 ์ž๋ฃŒํ˜• ๋•Œ๋ฌธ์— ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ๊ฐ€ ๋ฐœ์ƒํ•  ๊ฒƒ์ด๋‹ค) + +์žฌ๊ท€ ํŠธ๋ฆฌ๋ฅผ ๊ทธ๋ ค๋ณด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.(์‚ฌ๊ฐํ˜•์œผ๋กœ ํ‘œ์‹œ๋œ ๋ถ€๋ถ„์€ ์บ์‹œ๊ฐ’์„ ๊ทธ๋Œ€๋กœ ๋ฐ˜ํ™˜ํ•œ ๊ฒฝ์šฐ๋ฅผ ๋‚˜ํƒ€๋‚ธ๋‹ค) + +![](/assets/img/chaeshee0908/coding-interview-univ/11.-Recursion-&-Dynamic-programming/3.png){: width="600" } + +์ด ํŠธ๋ฆฌ์—์„œ ๊ฐ ๋…ธ๋“œ์˜ ์ž์‹ ๋…ธ๋“œ๋Š” ํ•œ ๊ฐœ์ด๋ฏ€๋กœ, ๋ชจ๋“  ๋…ธ๋“œ์˜ ๊ฐœ์ˆ˜๋Š” ๋Œ€๋žต 2n๊ฐœ๊ฐ€ ๋œ๋‹ค. ๋”ฐ๋ผ์„œ ์ˆ˜ํ–‰ ์‹œ๊ฐ„์€ O(n)์ด๋‹ค. + +### ๋ฐฉ๋ฒ• #3: ์ƒํ–ฅ์‹ ๋™์  ํ”„๋กœ๊ทธ๋ž˜๋ฐ + +์žฌ๊ท€์ ์ธ ๋ฉ”๋ชจ์ด์ œ์ด์…˜์œผ๋กœ ์ ‘๊ทผํ•˜๋˜ ๊ทธ๊ฒƒ์„ ๋’ค์ง‘๋Š”๋‹ค๊ณ  ์ƒ๊ฐํ•ด๋ณด์ž. + +๋จผ์ €, ์ดˆ๊ธฐ ์‚ฌ๋ก€(base case)์ธ fib(1)๊ณผ fib(0)์„ ๊ณ„์‚ฐํ•œ๋‹ค. ๊ทธ ๋’ค, ์ด ๋‘˜์„ ์ด์šฉํ•ด fib(2)๋ฅผ ๊ณ„์‚ฐํ•˜๊ณ , ์ฐจ๋ก€๋กœ fib(3), fib(4) ๋“ฑ์„ ์ด์ „์˜ ๊ฒฐ๊ณผ๋ฅผ ์ด์šฉํ•ด ๊ณ„์‚ฐํ•œ๋‹ค. + +```java +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 ํ…Œ์ด๋ธ” ๋ง๊ณ  ๋ณ€์ˆ˜ ๋ช‡ ๊ฐœ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ํ’€ ์ˆ˜๋„ ์žˆ๋‹ค. + +```java +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)๋กœ ์˜ฎ๊ธฐ๋Š” ์ผ์„ ์ˆ˜ํ–‰ํ–ˆ๋‹ค. \ No newline at end of file