All language subtitles for 11. Recursion

af Afrikaans
ak Akan
sq Albanian
am Amharic
ar Arabic Download
hy Armenian
az Azerbaijani
eu Basque
be Belarusian
bem Bemba
bn Bengali
bh Bihari
bs Bosnian
br Breton
bg Bulgarian
km Cambodian
ca Catalan
ceb Cebuano
chr Cherokee
ny Chichewa
zh-CN Chinese (Simplified)
zh-TW Chinese (Traditional)
co Corsican
hr Croatian
cs Czech
da Danish
nl Dutch
en English
eo Esperanto
et Estonian
ee Ewe
fo Faroese
tl Filipino
fi Finnish
fr French
fy Frisian
gaa Ga
gl Galician
ka Georgian
de German
el Greek
gn Guarani
gu Gujarati
ht Haitian Creole
ha Hausa
haw Hawaiian
iw Hebrew
hi Hindi
hmn Hmong
hu Hungarian
is Icelandic
ig Igbo
id Indonesian
ia Interlingua
ga Irish
it Italian
ja Japanese
jw Javanese
kn Kannada
kk Kazakh
rw Kinyarwanda
rn Kirundi
kg Kongo
ko Korean
kri Krio (Sierra Leone)
ku Kurdish
ckb Kurdish (Soranî)
ky Kyrgyz
lo Laothian
la Latin
lv Latvian
ln Lingala
lt Lithuanian
loz Lozi
lg Luganda
ach Luo
lb Luxembourgish
mk Macedonian
mg Malagasy
ms Malay
ml Malayalam
mt Maltese
mi Maori
mr Marathi
mfe Mauritian Creole
mo Moldavian
mn Mongolian
my Myanmar (Burmese)
sr-ME Montenegrin
ne Nepali
pcm Nigerian Pidgin
nso Northern Sotho
no Norwegian
nn Norwegian (Nynorsk)
oc Occitan
or Oriya
om Oromo
ps Pashto
fa Persian
pl Polish
pt-BR Portuguese (Brazil)
pt Portuguese (Portugal)
pa Punjabi
qu Quechua
ro Romanian
rm Romansh
nyn Runyakitara
ru Russian
sm Samoan
gd Scots Gaelic
sr Serbian
sh Serbo-Croatian
st Sesotho
tn Setswana
crs Seychellois Creole
sn Shona
sd Sindhi
si Sinhalese
sk Slovak
sl Slovenian
so Somali
es Spanish
es-419 Spanish (Latin American)
su Sundanese
sw Swahili
sv Swedish
tg Tajik
ta Tamil
tt Tatar
te Telugu
th Thai
ti Tigrinya
to Tonga
lua Tshiluba
tum Tumbuka
tr Turkish
tk Turkmen
tw Twi
ug Uighur
uk Ukrainian
ur Urdu
uz Uzbek
vi Vietnamese
cy Welsh
wo Wolof
xh Xhosa
yi Yiddish
yo Yoruba
zu Zulu
Would you like to inspect the original subtitles? These are the user uploaded subtitles that are being translated: 1 1 00:00:00,211 --> 00:00:05,211 (lively music) (keyboard clacking) 2 2 00:00:05,320 --> 00:00:07,970 The next couple of algorithms we'll look at 3 3 00:00:07,970 --> 00:00:09,610 can be written recursively 4 4 00:00:09,610 --> 00:00:11,710 and they're often written recursively, 5 5 00:00:11,710 --> 00:00:14,092 so let's take a brief timeout 6 6 00:00:14,092 --> 00:00:16,020 and talk about recursion 7 7 00:00:16,020 --> 00:00:18,360 to make sure we're all on the same page. 8 8 00:00:18,360 --> 00:00:22,100 A method is a recursive method when it calls itself, 9 9 00:00:22,100 --> 00:00:25,420 so we're gonna take a look at calculating the factorial 10 10 00:00:25,420 --> 00:00:26,420 for a number. 11 11 00:00:26,420 --> 00:00:28,800 As a reminder to calculate the factorial, 12 12 00:00:28,800 --> 00:00:30,120 you start with the number 13 13 00:00:30,120 --> 00:00:33,350 and then you multiply it by number minus one 14 14 00:00:33,350 --> 00:00:36,210 and then you multiply the result by number minus two 15 15 00:00:36,210 --> 00:00:40,300 and you multiply that result by number minus three et cetera 16 16 00:00:40,300 --> 00:00:43,150 until you hit zero and then you stop. 17 17 00:00:43,150 --> 00:00:47,990 So, three factorial would be three times two times one 18 18 00:00:47,990 --> 00:00:49,340 which equals six. 19 19 00:00:49,340 --> 00:00:54,340 100 factorial would 100 times 99 times 98 20 20 00:00:54,370 --> 00:00:58,260 times 97, all the way down to times one 21 21 00:00:58,260 --> 00:01:03,260 and the result of that is 9.332622 to the power of 157 22 22 00:01:05,300 --> 00:01:06,840 which is a pretty large number. 23 23 00:01:06,840 --> 00:01:08,890 Now, how about zero factorial? 24 24 00:01:08,890 --> 00:01:11,520 Well, by definition that's equal to one. 25 25 00:01:11,520 --> 00:01:13,950 So, zero factorial is one. 26 26 00:01:13,950 --> 00:01:15,950 If you're wondering about negative numbers, 27 27 00:01:15,950 --> 00:01:19,370 the factorials for negative numbers are undefined. 28 28 00:01:19,370 --> 00:01:23,600 So, I have on the screen the factorial algorithm, 29 29 00:01:23,600 --> 00:01:25,810 the steps for calculating the factorial. 30 30 00:01:25,810 --> 00:01:28,870 We start out by saying if num is equal to zero, 31 31 00:01:28,870 --> 00:01:31,240 so if we're taking num factorial, 32 32 00:01:31,240 --> 00:01:32,700 if num is equal to zero, 33 33 00:01:32,700 --> 00:01:34,080 then the factorial is one 34 34 00:01:34,080 --> 00:01:36,200 and we stop, we have the result. 35 35 00:01:36,200 --> 00:01:38,910 Otherwise we set the multiplier to one 36 36 00:01:38,910 --> 00:01:41,160 and we set the factorial to one 37 37 00:01:41,160 --> 00:01:44,440 and then while the multiplier is not equal to num, 38 38 00:01:44,440 --> 00:01:46,420 we do steps five and six. 39 39 00:01:46,420 --> 00:01:49,750 We multiply factorial by multiplier 40 40 00:01:49,750 --> 00:01:51,950 and we assign the result to factorial 41 41 00:01:51,950 --> 00:01:54,130 and then we add one to multiplier 42 42 00:01:54,130 --> 00:01:57,060 and so, we'll say one times one, 43 43 00:01:57,060 --> 00:02:00,120 add one to multiplier, so multiplier will become two, 44 44 00:02:00,120 --> 00:02:02,770 so we'll have one times one times two 45 45 00:02:02,770 --> 00:02:05,370 and then we'll assign two to factorial 46 46 00:02:05,370 --> 00:02:07,200 and then we'll multiply that by three 47 47 00:02:07,200 --> 00:02:09,320 and so, we'll assign six to factorial, 48 48 00:02:09,320 --> 00:02:10,740 we'll multiply that by four, 49 49 00:02:10,740 --> 00:02:13,220 assign 24 to factorial et cetera 50 50 00:02:13,220 --> 00:02:15,640 and we keep going until multiplier 51 51 00:02:15,640 --> 00:02:18,020 is equal to num at which point we stop. 52 52 00:02:18,020 --> 00:02:19,380 So, that's another way of looking at it 53 53 00:02:19,380 --> 00:02:23,030 instead of counting down and going three times two times one 54 54 00:02:23,030 --> 00:02:24,450 for six factorial, 55 55 00:02:24,450 --> 00:02:27,270 we can also say one times two times three. 56 56 00:02:27,270 --> 00:02:28,800 It'll give us the same result. 57 57 00:02:28,800 --> 00:02:30,050 So, in this algorithm, 58 58 00:02:30,050 --> 00:02:32,360 we basically have a rinse-and-repeat step 59 59 00:02:32,360 --> 00:02:33,924 which is step number four. 60 60 00:02:33,924 --> 00:02:36,890 Step number four says that while the multiplier 61 61 00:02:36,890 --> 00:02:40,440 is not equal to num, do steps five to six. 62 62 00:02:40,440 --> 00:02:42,273 So, how would we code this? 63 63 00:02:42,273 --> 00:02:44,800 Let's go out to IntelliJ 64 64 00:02:44,800 --> 00:02:45,960 and we'll write the function 65 65 00:02:45,960 --> 00:02:49,840 that calculates the factorial in an iterative way. 66 66 00:02:49,840 --> 00:02:51,483 So, we'll use a for loop. 67 67 00:02:57,250 --> 00:03:00,370 So, here I am in IntelliJ and I've created a project, 68 68 00:03:00,370 --> 00:03:03,890 the package is academy.learnprogramming.recursion 69 69 00:03:03,890 --> 00:03:06,268 and I'm going to write a method 70 70 00:03:06,268 --> 00:03:09,950 to calculate the factorial in an iterative fashion 71 71 00:03:09,950 --> 00:03:13,060 and that means we're not going to use recursion. 72 72 00:03:13,060 --> 00:03:15,260 So, I'm gonna say public static, 73 73 00:03:15,260 --> 00:03:18,060 static because we'll be calling it from the main method, 74 74 00:03:18,060 --> 00:03:19,360 it's gonna return an integer, 75 75 00:03:19,360 --> 00:03:23,200 the factorial and I'll call it iterativeFactorial 76 76 00:03:23,200 --> 00:03:25,313 and of course we wanna pass in num. 77 77 00:03:27,150 --> 00:03:30,010 So, the first thing we'll check is whether num equals zero 78 78 00:03:30,010 --> 00:03:31,530 because if num equals zero, 79 79 00:03:31,530 --> 00:03:34,523 we know that the result is one. 80 80 00:03:36,050 --> 00:03:37,600 And so, we'll just return one. 81 81 00:03:37,600 --> 00:03:39,410 If num doesn't equal zero, 82 82 00:03:39,410 --> 00:03:43,520 we'll set a field called factorial to one 83 83 00:03:43,520 --> 00:03:46,720 and then we'll say for int i equals one, 84 84 00:03:46,720 --> 00:03:50,220 i less than or equal to num, i++ 85 85 00:03:54,030 --> 00:03:57,363 factorial is assigned factorial times i. 86 86 00:04:01,330 --> 00:04:02,650 And when we drop out of the loop, 87 87 00:04:02,650 --> 00:04:05,600 we have the factorial, so we'll just return that. 88 88 00:04:05,600 --> 00:04:06,790 So, what's happening here, 89 89 00:04:06,790 --> 00:04:09,580 let's say we wanted to calculate three factorial 90 90 00:04:09,580 --> 00:04:10,870 'cause we know that that's six, 91 91 00:04:10,870 --> 00:04:12,760 so num is not equal to zero, 92 92 00:04:12,760 --> 00:04:16,130 so we don't return, we'll set factorial to one, 93 93 00:04:16,130 --> 00:04:18,080 i has to be less than or equal to three, 94 94 00:04:18,080 --> 00:04:19,730 'cause we're passing in three, 95 95 00:04:19,730 --> 00:04:22,916 so on the first iteration, the loop factorial 96 96 00:04:22,916 --> 00:04:26,280 will be assigned factorial times one 97 97 00:04:26,280 --> 00:04:28,690 and we start out with factorial being one, 98 98 00:04:28,690 --> 00:04:31,630 so factorial will get one times one which is one, 99 99 00:04:31,630 --> 00:04:34,830 i will become two, so factorial gets one times two 100 100 00:04:34,830 --> 00:04:37,490 which is two and then i becomes three, 101 101 00:04:37,490 --> 00:04:40,810 so factorial gets two times three which six 102 102 00:04:40,810 --> 00:04:41,730 and then at this point, 103 103 00:04:41,730 --> 00:04:45,310 i becomes four, it's no longer less than or equal to num, 104 104 00:04:45,310 --> 00:04:46,300 so we drop out 105 105 00:04:46,300 --> 00:04:48,690 and so, we return six. 106 106 00:04:48,690 --> 00:04:51,330 So, that means three factorial is six. 107 107 00:04:51,330 --> 00:04:54,480 And so, this an iterative implementation. 108 108 00:04:54,480 --> 00:04:55,567 We're not using recursion, 109 109 00:04:55,567 --> 00:04:57,880 the method does not call itself. 110 110 00:04:57,880 --> 00:05:00,820 So, what about a recursive implementation? 111 111 00:05:00,820 --> 00:05:02,330 Well, instead of using the loop, 112 112 00:05:02,330 --> 00:05:04,190 we can have the method call itself 113 113 00:05:04,190 --> 00:05:05,890 because think about it, 114 114 00:05:05,890 --> 00:05:09,820 two factorial is one factorial times two, 115 115 00:05:09,820 --> 00:05:13,910 three factorial is two factorial times three, 116 116 00:05:13,910 --> 00:05:17,720 four factorial is three factorial times four. 117 117 00:05:17,720 --> 00:05:20,043 I'm gonna write these out in a comment 118 118 00:05:20,043 --> 00:05:22,060 so you can see what I mean, 119 119 00:05:22,060 --> 00:05:25,570 so one factorial and usually we write factorial 120 120 00:05:25,570 --> 00:05:26,810 using exclamation marks, 121 121 00:05:26,810 --> 00:05:30,710 so one factorial equals zero factorial 122 122 00:05:30,710 --> 00:05:33,420 which we know is one times one 123 123 00:05:33,420 --> 00:05:36,150 which equals one, right? 124 124 00:05:36,150 --> 00:05:39,840 Two factorial equals two times one 125 125 00:05:40,780 --> 00:05:45,780 and this is actually two times one factorial 126 126 00:05:46,350 --> 00:05:49,063 because we know that one factorial is one. 127 127 00:05:50,570 --> 00:05:55,570 Three factorial equals three times two 128 128 00:05:56,460 --> 00:06:00,880 times one and that's equivalent to three 129 129 00:06:02,330 --> 00:06:04,730 times two factorial 130 130 00:06:04,730 --> 00:06:07,970 because two factorial is two times one, 131 131 00:06:07,970 --> 00:06:10,233 so that's three times two factorial. 132 132 00:06:11,420 --> 00:06:14,880 Four factorial is equal to four 133 133 00:06:14,880 --> 00:06:18,630 times three times two times one. 134 134 00:06:18,630 --> 00:06:21,454 And that's equivalent to four 135 135 00:06:21,454 --> 00:06:25,070 times three factorial because three factorial 136 136 00:06:25,070 --> 00:06:27,290 is equal to three times two times one. 137 137 00:06:27,290 --> 00:06:29,190 So, you can see the pattern now. 138 138 00:06:29,190 --> 00:06:32,210 So, one factorial is I guess I should reverse that 139 139 00:06:32,210 --> 00:06:36,220 for consistency, so one times zero factorial, 140 140 00:06:36,220 --> 00:06:38,280 two factorial is two times one 141 141 00:06:38,280 --> 00:06:41,200 which is two times one factorial, 142 142 00:06:41,200 --> 00:06:44,030 three factorial is three times two times one 143 143 00:06:44,030 --> 00:06:47,080 which is equivalent to three times two factorial, 144 144 00:06:47,080 --> 00:06:49,410 four factorial is four times three 145 145 00:06:49,410 --> 00:06:51,090 times two times one 146 146 00:06:51,090 --> 00:06:53,860 which is equivalent to four times three factorial. 147 147 00:06:53,860 --> 00:06:56,750 Five factorial would be five times four 148 148 00:06:56,750 --> 00:06:59,000 times three times two times one 149 149 00:06:59,000 --> 00:07:02,430 which is equivalent to five times four factorial. 150 150 00:07:02,430 --> 00:07:05,240 And so, to calculate each factorial, 151 151 00:07:05,240 --> 00:07:08,070 we can use a factorial. 152 152 00:07:08,070 --> 00:07:11,770 Basically we multiply the num, the number 153 153 00:07:11,770 --> 00:07:15,070 by n minus one factorial. 154 154 00:07:15,070 --> 00:07:16,790 So, basically we're doing the following. 155 155 00:07:16,790 --> 00:07:21,790 To get n factorial, that equals n minus one factorial 156 156 00:07:23,010 --> 00:07:25,230 times n, right? 157 157 00:07:25,230 --> 00:07:26,280 I'll do it like that 158 158 00:07:26,280 --> 00:07:29,011 because that's how I wrote it above. 159 159 00:07:29,011 --> 00:07:32,720 So, basically this is the formula we can use 160 160 00:07:32,720 --> 00:07:34,480 to get the factorial of n, 161 161 00:07:34,480 --> 00:07:38,140 it's equal to n times n minus one factorial. 162 162 00:07:38,140 --> 00:07:39,470 And so, let's write a method 163 163 00:07:39,470 --> 00:07:41,120 that uses this information. 164 164 00:07:41,120 --> 00:07:43,870 So, we'll say public static int 165 165 00:07:43,870 --> 00:07:46,443 and we'll call this one recursiveFactorial 166 166 00:07:47,770 --> 00:07:50,020 and we'll pass in num as we did before 167 167 00:07:51,330 --> 00:07:52,810 and we'll start out the same way. 168 168 00:07:52,810 --> 00:07:54,593 If num equals zero, 169 169 00:07:56,150 --> 00:07:57,390 then we return one. 170 170 00:07:57,390 --> 00:08:00,080 We know that zero factorial is one. 171 171 00:08:00,080 --> 00:08:02,030 Otherwise what are we gonna return? 172 172 00:08:02,030 --> 00:08:07,030 Num times recursiveFactorial of num minus one. 173 173 00:08:08,250 --> 00:08:11,040 Because we've just said that we can calculate 174 174 00:08:11,040 --> 00:08:14,180 the factorial of n by multiplying n 175 175 00:08:14,180 --> 00:08:16,930 by n minus one factorial 176 176 00:08:16,930 --> 00:08:20,380 and so, here we're calling the same method, 177 177 00:08:20,380 --> 00:08:22,300 we're calling the method itself 178 178 00:08:22,300 --> 00:08:25,070 to get the value and here you can notice in the gutter, 179 179 00:08:25,070 --> 00:08:27,570 IntelliJ has added this icon here 180 180 00:08:27,570 --> 00:08:29,960 to tell us that we're making a recursive call. 181 181 00:08:29,960 --> 00:08:32,100 But how does this actually work? 182 182 00:08:32,100 --> 00:08:33,280 Let me move this up. 183 183 00:08:33,280 --> 00:08:35,990 So, let's say we call recursiveFactorial 184 184 00:08:35,990 --> 00:08:37,570 with a value of three. 185 185 00:08:37,570 --> 00:08:40,160 Well, we're going to say does num equal zero? 186 186 00:08:40,160 --> 00:08:41,770 No, it doesn't, so we'll come down 187 187 00:08:41,770 --> 00:08:42,603 and we'll say okay, 188 188 00:08:42,603 --> 00:08:47,240 we want to return three times recursiveFactorial of two. 189 189 00:08:47,240 --> 00:08:49,040 Now, this doesn't return right away 190 190 00:08:49,040 --> 00:08:50,530 because what's gonna happen 191 191 00:08:50,530 --> 00:08:54,730 is we have to wait until we get the value 192 192 00:08:54,730 --> 00:08:57,780 of recursiveFactorial num minus one, 193 193 00:08:57,780 --> 00:08:58,970 and so, what will happen 194 194 00:08:58,970 --> 00:09:02,200 is the call to recursiveFactorial 195 195 00:09:02,200 --> 00:09:04,930 with a value of three is going to pushed 196 196 00:09:04,930 --> 00:09:07,380 onto what's called the call stack 197 197 00:09:07,380 --> 00:09:09,830 and then recursiveFactorial two 198 198 00:09:09,830 --> 00:09:11,780 is going to be executed. 199 199 00:09:11,780 --> 00:09:15,220 So, we haven't returned from recursiveFactorial three 200 200 00:09:15,220 --> 00:09:17,200 'cause we have to wait for this result 201 201 00:09:17,200 --> 00:09:19,350 and then we come into recursiveFactorial 202 202 00:09:19,350 --> 00:09:21,300 with two into this call, 203 203 00:09:21,300 --> 00:09:24,250 num isn't zero, so this time we're going to want 204 204 00:09:24,250 --> 00:09:27,680 to return two times recursiveFactorial 205 205 00:09:27,680 --> 00:09:29,670 of two minus one which is one, 206 206 00:09:29,670 --> 00:09:32,080 so now the recursiveFactorial call 207 207 00:09:32,080 --> 00:09:34,280 with the value two has to wait 208 208 00:09:34,280 --> 00:09:36,060 and so, it's going to get pushed 209 209 00:09:36,060 --> 00:09:37,760 onto the call stack 210 210 00:09:37,760 --> 00:09:41,090 and recursiveFactorial one is going to be called. 211 211 00:09:41,090 --> 00:09:43,980 So, basically at this point, we have two calls 212 212 00:09:43,980 --> 00:09:46,310 to recursiveFactorial that are waiting 213 213 00:09:46,310 --> 00:09:47,760 for a return value, 214 214 00:09:47,760 --> 00:09:50,303 we call recursiveFactorial one, 215 215 00:09:50,303 --> 00:09:53,600 one isn't zero, so we're gonna come down here 216 216 00:09:53,600 --> 00:09:56,880 and return one times recursiveFactorial 217 217 00:09:56,880 --> 00:09:58,530 of one minus one which is zero. 218 218 00:09:58,530 --> 00:10:02,040 So, now the recursiveFactorial call with one 219 219 00:10:02,040 --> 00:10:03,610 is gonna get pushed on the stack 220 220 00:10:03,610 --> 00:10:07,610 because it's waiting and we call recursiveFactorial zero, 221 221 00:10:07,610 --> 00:10:09,020 so we're gonna come in here, 222 222 00:10:09,020 --> 00:10:11,140 ah, this time num is zero, 223 223 00:10:11,140 --> 00:10:14,950 so we return one and this call is finished, 224 224 00:10:14,950 --> 00:10:16,650 it doesn't get pushed onto the stack 225 225 00:10:16,650 --> 00:10:20,720 but now the recursiveFactorial call with zero returns 226 226 00:10:20,720 --> 00:10:23,520 and that's the call that recursiveFactorial 227 227 00:10:23,520 --> 00:10:25,910 with the value one is waiting for. 228 228 00:10:25,910 --> 00:10:28,320 So, now that call can resume 229 229 00:10:28,320 --> 00:10:31,010 and it gets the return value of one 230 230 00:10:31,010 --> 00:10:33,240 and so, it multiplies one by one 231 231 00:10:33,240 --> 00:10:34,610 and it returns one 232 232 00:10:34,610 --> 00:10:37,900 and now the call to recursiveFactorial two 233 233 00:10:37,900 --> 00:10:39,600 can resume because it was waiting 234 234 00:10:39,600 --> 00:10:42,980 for the return value of recursiveFactorial one. 235 235 00:10:42,980 --> 00:10:45,420 And so, it multiplies two by one, 236 236 00:10:45,420 --> 00:10:47,790 to get two, it returns two 237 237 00:10:47,790 --> 00:10:51,540 and now the call to recursiveFactorial three can resume 238 238 00:10:51,540 --> 00:10:53,980 because it was waiting for the return value 239 239 00:10:53,980 --> 00:10:56,260 of recursiveFactorial two. 240 240 00:10:56,260 --> 00:10:58,580 And so, it multiplies three by two, 241 241 00:10:58,580 --> 00:11:01,540 it gets six, it returns and we have finished, 242 242 00:11:01,540 --> 00:11:04,520 there's no more calls to recursiveFactorial 243 243 00:11:04,520 --> 00:11:05,830 waiting on the call stack 244 244 00:11:05,830 --> 00:11:07,970 and so, six gets returned 245 245 00:11:07,970 --> 00:11:09,680 but you'll notice that the order 246 246 00:11:09,680 --> 00:11:12,120 in which the recursive calls are made, 247 247 00:11:12,120 --> 00:11:14,840 they return in the reverse order. 248 248 00:11:14,840 --> 00:11:17,963 So, basically the situation that we have, 249 249 00:11:19,060 --> 00:11:23,650 so we start out with calling recursiveFactorial three 250 250 00:11:23,650 --> 00:11:25,180 and when it hits this line, 251 251 00:11:25,180 --> 00:11:27,100 it calls recursiveFactorial two. 252 252 00:11:27,100 --> 00:11:30,010 So, it can't return until it gets the value 253 253 00:11:30,010 --> 00:11:32,640 of recursiveFactorial two and so, the call 254 254 00:11:32,640 --> 00:11:35,280 to recursiveFactorial three 255 255 00:11:36,520 --> 00:11:38,770 gets pushed onto the call stack. 256 256 00:11:38,770 --> 00:11:41,340 Then recursiveFactorial two is called. 257 257 00:11:41,340 --> 00:11:44,040 It can't return until it gets the result 258 258 00:11:44,040 --> 00:11:45,893 of recursiveFactorial one. 259 259 00:11:47,260 --> 00:11:50,843 And so, it gets pushed onto the call stack. 260 260 00:11:53,120 --> 00:11:57,150 And then recursiveFactorial one 261 261 00:11:57,150 --> 00:11:59,090 will get pushed onto the call stack 262 262 00:11:59,090 --> 00:12:02,080 and recursiveFactorial zero 263 263 00:12:02,080 --> 00:12:04,080 will actually return right away, 264 264 00:12:04,080 --> 00:12:07,510 so when recursiveFactorial zero returns, 265 265 00:12:07,510 --> 00:12:10,480 this gets popped off the call stack 266 266 00:12:10,480 --> 00:12:12,080 and it continues executing 267 267 00:12:12,080 --> 00:12:13,500 and it will return one 268 268 00:12:13,500 --> 00:12:15,960 and when that returns, this gets popped up 269 269 00:12:15,960 --> 00:12:19,170 off the call stack, it continues executing 270 270 00:12:19,170 --> 00:12:20,760 and returns the value two 271 271 00:12:20,760 --> 00:12:24,270 and finally this gets popped off the call stack 272 272 00:12:24,270 --> 00:12:26,850 and it returns the value six. 273 273 00:12:26,850 --> 00:12:28,740 That's how recursion works. 274 274 00:12:28,740 --> 00:12:31,150 And it's important to see that when you enter 275 275 00:12:31,150 --> 00:12:33,390 a recursive method, it might be a while 276 276 00:12:33,390 --> 00:12:34,860 before it returns. 277 277 00:12:34,860 --> 00:12:36,580 You can go down the rabbit hole 278 278 00:12:36,580 --> 00:12:39,390 and you can go down, so when you see recursion 279 279 00:12:39,390 --> 00:12:41,240 in the upcoming sort algorithms 280 280 00:12:41,240 --> 00:12:42,630 that we're going to look at, 281 281 00:12:42,630 --> 00:12:46,150 keep in mind that the call to a recursive method 282 282 00:12:46,150 --> 00:12:48,570 may result in many more calls 283 283 00:12:48,570 --> 00:12:51,760 before it returns, so it's important to understand 284 284 00:12:51,760 --> 00:12:54,300 that a three-line recursive method 285 285 00:12:54,300 --> 00:12:57,250 could result in hundreds of recursive calls. 286 286 00:12:57,250 --> 00:12:59,150 The code might look simple 287 287 00:12:59,150 --> 00:13:01,440 but it can lead to a tonne of processing. 288 288 00:13:01,440 --> 00:13:03,440 And it's really important to understand 289 289 00:13:03,440 --> 00:13:06,630 that none of the recursive calls return 290 290 00:13:06,630 --> 00:13:09,120 until they receive the result 291 291 00:13:09,120 --> 00:13:11,720 from the method that they invoked recursively, 292 292 00:13:11,720 --> 00:13:15,080 so as we saw, recursiveFactorial three 293 293 00:13:15,080 --> 00:13:16,263 invoked recursiveFactorial two, 294 294 00:13:17,506 --> 00:13:20,830 so recursiveFactorial three is not going to return, 295 295 00:13:20,830 --> 00:13:24,690 it can't return until recursiveFactorial two 296 296 00:13:24,690 --> 00:13:26,233 has finished executing. 297 297 00:13:27,890 --> 00:13:32,350 You'll notice here that the recursive calls 298 298 00:13:32,350 --> 00:13:35,260 are ended when we pass num equals zero 299 299 00:13:35,260 --> 00:13:37,330 because when we pass in num equals zero, 300 300 00:13:37,330 --> 00:13:40,590 we don't make a recursive call, we just return one. 301 301 00:13:40,590 --> 00:13:42,640 If we didn't have this condition, 302 302 00:13:42,640 --> 00:13:46,120 we'd never end, we'd just keep making recursive call 303 303 00:13:46,120 --> 00:13:48,710 after recursive call after recursive call. 304 304 00:13:48,710 --> 00:13:51,210 So, in order for recursion to work properly, 305 305 00:13:51,210 --> 00:13:53,010 you need some condition 306 306 00:13:53,010 --> 00:13:54,937 that's going to end the recursion. 307 307 00:13:54,937 --> 00:13:58,930 And that condition is known as the breaking condition 308 308 00:13:58,930 --> 00:14:01,160 and it's also called the base case. 309 309 00:14:01,160 --> 00:14:03,870 So, in the recursiveFactorial method, 310 310 00:14:03,870 --> 00:14:06,630 this if num equals zero condition 311 311 00:14:06,630 --> 00:14:09,960 is the base case or the breaking condition. 312 312 00:14:09,960 --> 00:14:12,570 At that point, when num equals zero, 313 313 00:14:12,570 --> 00:14:15,746 we say that the recursion starts to unwind, 314 314 00:14:15,746 --> 00:14:18,800 so at that point it's gonna return a value 315 315 00:14:18,800 --> 00:14:21,520 and the method that invoked it recursively 316 316 00:14:21,520 --> 00:14:23,630 will now be able to continue executing 317 317 00:14:23,630 --> 00:14:25,230 and then it will return a value 318 318 00:14:25,230 --> 00:14:27,250 and the method that invoked it recursively 319 319 00:14:27,250 --> 00:14:30,580 will be able to continue executing et cetera. 320 320 00:14:30,580 --> 00:14:32,070 So, when you use recursion, 321 321 00:14:32,070 --> 00:14:33,800 you need a breaking condition. 322 322 00:14:33,800 --> 00:14:35,045 If you don't have one, 323 323 00:14:35,045 --> 00:14:36,870 what will happen is the method 324 324 00:14:36,870 --> 00:14:38,710 will keep calling itself recursively 325 325 00:14:38,710 --> 00:14:41,780 and eventually you'll get a stack overflow exception 326 326 00:14:41,780 --> 00:14:44,590 because the call stack only has a certain amount 327 327 00:14:44,590 --> 00:14:46,410 of memory allocated to it. 328 328 00:14:46,410 --> 00:14:48,530 And so, eventually you'll blow that memory. 329 329 00:14:48,530 --> 00:14:50,700 So, let's run our recursive code. 330 330 00:14:50,700 --> 00:14:52,450 Well, we'll run them both actually. 331 331 00:14:57,090 --> 00:14:59,690 Let's System.out.print line 332 332 00:14:59,690 --> 00:15:03,090 and we'll print out iterativeFactorial of three 333 333 00:15:04,837 --> 00:15:08,920 and we'll do the same thing for recursiveFactorial three 334 334 00:15:08,920 --> 00:15:11,650 and we should see six in both cases. 335 335 00:15:11,650 --> 00:15:12,483 Let's run. 336 336 00:15:15,330 --> 00:15:17,900 And sure enough, we get two sixes. 337 337 00:15:17,900 --> 00:15:20,420 For fun, for fun and giggles, 338 338 00:15:20,420 --> 00:15:25,180 let's remove the or just comment out this breaking condition 339 339 00:15:25,180 --> 00:15:26,840 and you're gonna see what happens here, 340 340 00:15:26,840 --> 00:15:28,090 it's not gonna be pretty. 341 341 00:15:31,130 --> 00:15:32,480 And look at that. 342 342 00:15:32,480 --> 00:15:34,980 We get all these recursive calls 343 343 00:15:34,980 --> 00:15:39,250 until eventually we get a stack overflow error. 344 344 00:15:39,250 --> 00:15:42,210 And so, we just keep, this method just keeps calling itself 345 345 00:15:42,210 --> 00:15:43,760 and calling itself and calling itself 346 346 00:15:43,760 --> 00:15:46,010 and there's nothing to stop it from doing that 347 347 00:15:46,010 --> 00:15:48,410 and so, we have all these, 348 348 00:15:48,410 --> 00:15:50,740 you're actually looking here at the call stack here, 349 349 00:15:50,740 --> 00:15:52,830 so you're looking at all of the methods 350 350 00:15:52,830 --> 00:15:53,880 that are on the call stack 351 351 00:15:53,880 --> 00:15:57,330 and as you can see, it just keeps invoking itself 352 352 00:15:57,330 --> 00:16:00,570 until we blow the call stack space. 353 353 00:16:00,570 --> 00:16:02,033 I'll uncomment that now. 354 354 00:16:03,558 --> 00:16:05,430 So, that's recursion. 355 355 00:16:05,430 --> 00:16:07,770 Now, here's something interesting. 356 356 00:16:07,770 --> 00:16:11,810 The iterative implementation usually runs faster 357 357 00:16:11,810 --> 00:16:13,920 and it doesn't use as much memory 358 358 00:16:13,920 --> 00:16:18,920 because there's overhead involved with pushing method calls 359 359 00:16:18,990 --> 00:16:20,640 onto the call stack 360 360 00:16:20,640 --> 00:16:23,810 and each stack frame uses some memory 361 361 00:16:23,810 --> 00:16:26,850 but sometimes the iterative way isn't as intuitive 362 362 00:16:26,850 --> 00:16:28,940 or if you write the algorithm 363 363 00:16:28,940 --> 00:16:32,890 in an iterative way, it'll be like a 500-line method 364 364 00:16:32,890 --> 00:16:34,250 or something like that, 365 365 00:16:34,250 --> 00:16:36,870 so developers still use recursion 366 366 00:16:36,870 --> 00:16:38,740 because it's often the most elegant 367 367 00:16:38,740 --> 00:16:41,760 and more easier to understand solution. 368 368 00:16:41,760 --> 00:16:43,897 Now, when we're dealing with the recursive method, 369 369 00:16:43,897 --> 00:16:45,840 the call stack can also be referred 370 370 00:16:45,840 --> 00:16:47,850 to as the recursion stack 371 371 00:16:47,850 --> 00:16:50,340 and we saw that when we don't have a breaking condition, 372 372 00:16:50,340 --> 00:16:52,320 we'll get a stack overflow exception. 373 373 00:16:52,320 --> 00:16:54,470 It's possible to get that exception 374 374 00:16:54,470 --> 00:16:56,960 even when you do have a breaking condition. 375 375 00:16:56,960 --> 00:16:58,900 If you write a recursive method 376 376 00:16:58,900 --> 00:17:01,910 and it invokes itself 1,000 times, 377 377 00:17:01,910 --> 00:17:03,330 you're still possibly going 378 378 00:17:03,330 --> 00:17:05,210 to get a stack overflow exception 379 379 00:17:05,210 --> 00:17:07,700 because you're not hitting that breaking condition. 380 380 00:17:07,700 --> 00:17:10,100 So, even if you have a breaking condition, 381 381 00:17:10,100 --> 00:17:11,883 if you call the recursive method 382 382 00:17:11,883 --> 00:17:14,400 with something that's going to cause the method 383 383 00:17:14,400 --> 00:17:16,650 to invoke itself a million times, 384 384 00:17:16,650 --> 00:17:18,450 you're gonna get a stack overflow error. 385 385 00:17:18,450 --> 00:17:20,080 So, just keep that in mind. 386 386 00:17:20,080 --> 00:17:23,280 Now, this is a way around this potential blowing 387 387 00:17:23,280 --> 00:17:25,620 of the stack, it's called tail recursion 388 388 00:17:25,620 --> 00:17:27,840 but we're not going to see that for two reasons. 389 389 00:17:27,840 --> 00:17:30,620 First of all, none of the algorithms we look at, 390 390 00:17:30,620 --> 00:17:33,810 none of the implementations use tail recursion 391 391 00:17:33,810 --> 00:17:36,410 but the second and perhaps more important reason 392 392 00:17:36,410 --> 00:17:38,700 for Java is that the Java compiler 393 393 00:17:38,700 --> 00:17:40,710 doesn't use tail recursion, 394 394 00:17:40,710 --> 00:17:43,400 so we can use that type of recursion in Java. 395 395 00:17:43,400 --> 00:17:45,310 I'm just mentioning it to make you aware 396 396 00:17:45,310 --> 00:17:48,170 that it exists and if you wanna read up on it yourself, 397 397 00:17:48,170 --> 00:17:50,420 I've linked to a Dr. Dobbs article 398 398 00:17:50,420 --> 00:17:52,150 in the Resources section, 399 399 00:17:52,150 --> 00:17:54,660 so if you're interested in reading about tail recursion 400 400 00:17:54,660 --> 00:17:57,900 in Java, you can go ahead and take a look at that article. 401 401 00:17:57,900 --> 00:18:00,830 Anyway, I hope that this has refreshed your memory 402 402 00:18:00,830 --> 00:18:03,300 about recursion and now that we're all on the same page, 403 403 00:18:03,300 --> 00:18:06,830 we're gonna move on and look at a recursive sort algorithm 404 404 00:18:06,830 --> 00:18:08,100 called merge sort. 405 405 00:18:08,100 --> 00:18:09,650 I'll see you in the next video. 34570

Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.